Differences in running vim through the command line versus running it in the vim editor

I am trying to process a number of files. I noticed that there are discrepancies in the execution of a particular command from the command line (i.e. ex

mode). For example.

$cat poo.txt
big
red
dog
small
black
cat

$vim -c "2,$g/^dog/d|wq" poo.txt

$cat poo.txt
big
small
black
cat

      

It looks like I 2,$g/^dog/d|wq

removed the lines with red

and dog

. This confuses me because the command must: start on line 2 (go to EOF) and delete all lines starting with dog

. In this case, I expect the output to be as follows:

$ cat poo.txt 
big
red
small
black
cat

      

In fact, if I try this in the vim editor, this is the exact behavior that is observed.

QUESTION: What is the reason for the mismatch between version vim -c

and version vim

to run this command?

+3


source to share


1 answer


I think you need to replace double quotes with single quotes to prevent shell expansion $g

. From man bash

:

Enclosing characters in double quotes preserves the literal value of all
characters within the  quotes,  with the  exception  of  $,  `, \, and, 
when history expansion is enabled, !.

      

Currently your shell expands $g

inside your string as if it were an environment variable. But it is probably undefined, thus expanding to an empty string. So, even if you typed:

vim -c "2,$g/^dog/d|wq" poo.txt

      

Vim does not receive the command:

2,$g/^dog/d|wq

      

... but:

2,/^dog/d|wq

      

This command removes all lines from those whose address 2

to the next one that starts with dog

(in your case, this is the third line). Then it saves and exits.



But even if you replace the quotes, there is still a problem in your command. From :h :bar

:

These commands see the '|' as their argument, and can therefore not be
followed by another Vim command:

...
:global
...

      

The bar is interpreted :g

as part of its argument, not as a command completion. In your case, this means that whenever it finds a line that starts with dog

, it deletes it and then immediately saves and exits. So, if there are multiple lines dog

, only the first one will be deleted because it :g

will be saved and completed after processing the first one.

You need to hide |wq

from :g

, either by zeroing out the global command inside the line and executing it with :execute

, or by moving wq

to another -c {cmd}

. In general, you can try:

vim -c 'exe "2,\$g/^dog/d" | wq' poo.txt

      

or

vim -c '2,$g/^dog/d' -c 'wq' poo.txt

      

or

vim -c '2,$g/^dog/d' -cx poo.txt

      

+3


source







All Articles