2017-07-25 90 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