6

It seems that if I run the following inside the vim:

:w !wc -w

I get the word count of the file. But I don't understand the syntax. How does this work and how would I specify that I want the word count of a paragraph and not of the whole file?

Cratylus
  • 499
  • 3
  • 6
  • 12
  • What are you trying to reach? Counting the amount of words in a paragraph? – Bernhard Jun 16 '13 at 10:42
  • I want to understand the syntax of running external programs inside `vim` and this is just an example. In this specific example I get a word count which is useful feature but I don't know how to use the syntax to get information the way I would need. – Cratylus Jun 16 '13 at 10:45
  • See my comment to Evan's answer re: using VISUAL mode. – goldilocks Jun 16 '13 at 16:58

3 Answers3

5

When you issue :w !wc -w, vim creates a temporary file and then pipes that file to the command following the !, or rather it puts your data in a temporary file and asks your shell to execute a command that looks something like the following:

 (wc -w) < /tmp/vHhjUPf/2

Where that last part is some random folder/filename that vim stores your data in. One interesting thing to note, this command will fail in non-compliant shells like fish. This is because fish uses the (cmd) syntax for command substitution instead of its traditional use.

  • Is there any known workaround for fish shell? It seems like this would be a common bug, but some searching didn't turn up an answer. – n s May 29 '17 at 19:18
3

To specify a range of data to pass to an external command, type this:

:<range>w !<command>

For example,

:1,5w !wc -w

would count the number of words within the range enclosed by lines 1 and 5. Type :h 10.3 for more information on ranges.

You can also use

:<range>!<command>

to replace the contents of lines 1 to 5 with the output of the command, which is useful when using external commands to filter text. (e.g. for sorting.) Type :h ! for more information on filters.

If you wish to run an external command without having Vim pass text to its standard input, run the command like so: :!command.

  • You can also select a range from visual mode -- ie., if you select a block of text in VISUAL and then run an external command, just that block gets fed to the command's stdin. – goldilocks Jun 16 '13 at 16:46
  • 2
    In visual mode, `!` expands to `'<,'>!`. `<` and `>` are marks that mark the start and end of the current/last visual selection, respectively. `'mark` is the syntax for using a mark as part of a range. –  Jun 16 '13 at 17:39
1

The vim command :w simply writes to disk the current file.

Using :w newfilename you write the current file to a new filename.

The command :!ls -al run the external program ls with parameters -al and displays the result.

The command you mention (:w !wc -w) will (probably) simply write the current file into a pipe to a external commmand (wc -w) who in turn will count up the words in current file.

Volker Siegel
  • 16,983
  • 5
  • 52
  • 79
DavAlPi
  • 805
  • 6
  • 17