Use filter commands to process text

From Vim Tips Wiki

Jump to: navigation, search
Tip 374 Printable Monobook Previous Next

created 2002 · complexity basic · author zzapper · version 6.0


Here are some examples of filtering which show how to save output from Vim commands, or read text from a file, or send text to an external program while capturing the output from that program.

[edit] Capturing output

Redirection can capture the output generated by Vim commands.

Redirection to clipboard register + (or use any other register a-z):

:redir @+
:history
:g/fred/
  " any other commands
:redir END

The output from the commands used is now in register + which might pasted into a new buffer, for example by entering :new then typing "+p to paste.

If wanted, you can temporarily turn off Vim's paging so there will be no "More" prompts, as shown in the following example which outputs to register A (so output is appended to register a):

:redir @A
:set nomore
:echo 'History'
:history
:echo 'Scripts loaded'
:scriptnames
:set nomore
:redir END

Redirection to a file:

:redir > out.txt
:registers
  " any other commands
:redir END

The above writes to the new file out.txt. The command does nothing if that file already exists. To overwrite the file if it exists, use :redir! > out.txt. To create a new file or append to an existing file, use :redir >> out.txt.

Store glob results in register a:

" Clear @a (register a) because need to use A to append.
:let @a = ''
" Append all lines containing 'fred' to register a.
:g/fred/y A
" Append to a file (must use >>).
:'a,'b g/^Error/ .w >> errors.txt

The last command uses the :.w command which writes the current line (.) by appending it to file errors.txt.

[edit] Processing input

Get output from external commands:

:r !ls     " read output from running ls, after current line
:0r !ls    " after line 0 (before first line)
:-r !ls    " before current line ("-" is ".-1")
:r !dir    " use 'dir' on Windows

Filter current file using an external command (these examples use sort, but Vim has a built-in :help :sort command which should be used to sort lines):

:%!sort -u      " use an external program to sort all lines
:'a,'b!sort -u  " same, for lines from mark a to mark b inclusive

The term "filter" means to replace lines with the result from running a program. The original lines are sent as stdin to the program, and are replaced with stdout from the program. You can also filter using motion commands or visual selection:

!}sort          " sort from cursor to end of paragraph
3!}sort         " same, 3 paragraphs
3!!sort         " sort 3 lines
V               " start visual selection of lines
(move cursor)   " select some lines
!sort           " sort the visually selected lines

[edit] Simple filter example

Following is a Python program to sort the words on each line of standard input (each line is separately sorted).

# File sortwords.py
from sys import stdin
for line in stdin:
    print ' '.join(sorted(line.split()))

A file you are editing in Vim may include the following text:

this is a line with some words
words on each line will be sorted
fried banana and cream

Use this procedure to filter the text:

  • Press V on the first line, then jj to select three lines.
  • Type !python sortwords.py and press Enter.

The lines are replaced with the result from running the program:

a is line some this with words
be each line on sorted will words
and banana cream fried

[edit] References

[edit] Comments

The section about redirecting Vim commands has nothing to do at all with using filters, and neither does the stuff about :r !cmd. That plus the actual stuff about filters seems redundant with the content in Append_output_of_an_external_command. --Fritzophrenic 14:25, July 2, 2012 (UTC)

Personal tools