2017-07-25 92 views
3

我正在尝试处理一系列文件。我注意到从命令行运行特定命令(即ex模式)存在差异。例如。通过命令行运行vim与在vim编辑器中运行vim的区别

$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 

看来,2,$g/^dog/d|wq已经与reddog删除线。这使我困惑,因为命令应该:从第2行开始(进入EOF)并删除以dog开头的所有行。在这种情况下,我期望的输出是:

$ cat poo.txt 
big 
red 
small 
black 
cat 

事实上,如果我尝试这vim编辑器这是观察到的具体行为。

问题:运行此命令的vim -c版本与vim版本之间的差异是什么原因造成的?

回答

3

我认为你需要用单引号替换双引号,以防止你的shell扩展$g。从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, !. 

目前,你的shell扩展$g你的字符串里面,就好像它是一个环境变量。但它可能没有定义,因此扩展为空字符串。所以,即使你输入:

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

Vim不接收命令:

2,$g/^dog/d|wq 

...但:

2,/^dog/d|wq 

此命令删除所有行地址是2的那个,到下一个以dog开头的(在你的情况下它是第三行)。然后,它保存并退出。

但即使您替换了引号,您的命令仍然存在问题。 从:h :bar

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

... 
:global 
... 

该杆由:g解释为它的参数的一部分,而不是作为命令终止。就你而言,这意味着只要找到一行以dog开头的行,它就会将其删除,然后立即保存并退出。因此,如果有多行dog行,则只有第一行将被删除,因为:g将在处理完第一行后保存并退出。

你需要隐藏|wq:g,无论是包裹在字符串中的全球指挥与:execute执行它,或者在另一个-c {cmd}移动wq。总而言之,你可以尝试:

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

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

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