« 不是打 vi 的廣告, vim 的全域指令「:g」( global ) 不是打 vi 的廣告, vim 的選擇模式 ( visual mode ) »
Thu 8 Sep 2005
在看過 vim 的全域指令和 search 指令之後,你會不會也會想自己還有什麼需求可以叫 vim 做的呢?
今天我和布丁長輩還有DK長輩聊天的時候就講到一個問題:我可不可以知道到底這份文件有多少個我想要搜尋的字串?
當然啦,你如果會 vim 的全域指令你可能可以用 :g/pattern/p 之後,用 copy 的方式或是其他指令的組合把比對出來的東西存到另外一個檔案去,然後再用其他的工具(像是wc)計算行數。不過,這個方法,不夠方便。
比較辛苦一點的方式也可以用 /pattern 然後自己按 n 一個個算,不過… 我想可能會先算到瘋掉。
難道 vim 就只能這樣了嗎?
忘了是DK長輩還是布丁長輩說可以寫程式來算。不過 vim 的 script 寫法,我打算到後面再寫。我心裡想的是,應該有一行就可以解決的方法啊!
在 vim 裡面遇到問題的時候有兩個方式,第一個就是 :h 然後後面跟上你猜可能會有答案的關鍵字。不過這個方式我今天用了好幾次,感覺除了寫程式別無他途。可是,我就是不想寫程式。第二個方法就是到 www.vim.org 上找 tips 看,結果沒兩下就找到了這篇<Tip #860: count number of matches of a pattern>,後面的 comment 中有個人只用一行解決,看了就覺得「哎唷,怎麼就是沒想到呢?」其實用 vim 編輯文件想這些怎麼樣可以讓自己少打點或是只用一行指令解決的過程是很有趣的。這個人用的方法很簡單也很漂亮,但卻要用到我們之前提過的取代指令 :s :
:%s/pattern/&/g
& 代表的意思就是用來表示前面比對的字串,所以做這個指令其實對檔案本身並不會有什麼改變。但是由於做的是全域的取代置換, vim 會告訴你有從多少行中多少個字串被取代。輕輕鬆鬆很漂亮地用一行命令解決這個問題。
輸入只有一行的命令:

結果就會出現在最後一行上,而且不會改變到檔案本身:

11 Responses to “vim 小技巧: 計算有多少個搜尋關鍵字”
Comments
Trackbacks
- vim - feedss.com
[...] vim 小技巧: 計算有多少個搜尋關鍵字 ?在看過 vim 的全域指令和 search 指令之後,你會不會也會想自己還有什麼需求可以叫 vim 做的呢? … 當然啦,你如果會 vimhttp://greenisland.csie.nctu.edu.tw/wp/2005/09/08/327/ 2005年09月08日 22:11 [...]
- 資訊技術與心情:Xuite日誌
[...] / 引用(0)2006-02-21 21:41vim技巧—找出欲搜尋字樣的數目?自由軟體記得在http://greenisland.csie.nctu.edu.tw/wp/2005/09/08/327/看過(繼續閱讀)more心不在焉 / Xuite日誌 / 回應(0) / 引用(0)2006-02-16 [...]
September 9th, 2005 at 12:28 am
這招真的很妙 @@
September 9th, 2005 at 6:32 pm
在網路上發現原來有簡體中文說明檔喔!@@
我把它翻譯成繁體了...
你要嗎?
September 9th, 2005 at 10:20 pm
先謝謝您的好意。不知道您的是不是指的是這一份 vim 說明文件?其實不管是不是都好,因為現在正在寫的這個系列是把平常使用 vim 比較會用到的指令和情況寫出來,並以範例來說明。對於真的想看看 vim 到底能幹嘛,或是想學一下 vim 卻又不想面對龐然巨大的 vim help 的人來說,竊以為李果正先生摘出部分他覺得比較常用來講或是在下目前的方式可能是比較適合初學者。不過還是得說, vim help 仍舊是隨時尋找解答、增加自己 vim 功力的最佳源頭。
September 9th, 2005 at 11:19 pm
嗯嗯~
同意~
對著vim help都不知從何看起
我第一次用不夠十分鐘就移除了~
但看見很多關於vim的正面評論,
最主要是看見你的文章,
我就決心要去學一下了~
December 25th, 2005 at 3:07 am
哈哈……这一招实在是妙,学用VIM的过程中总是意料之外的东西,真让人着迷。。。
January 21st, 2006 at 3:25 am
in vim7, there’s a new substitute flags: n, which perform a pseudo replace, but report the number of items to replace. The consequence of :%s/pattern/&/gn won’t modify the file, this speed up the operation vastly.
for the purpose to report number of lines contain some pattern. Here’s also an alternative way:
:let n=0
:g/pattern/norm :let n=n+1^M
:echo n
[Note the character ^M is a single character, which should be input as in Unix and in windows/DOS]
So no need to copy the result of :g/pattern/p and then save to a separate file then wc it.
January 21st, 2006 at 3:27 am
Sorry for the wrong HTMLized result, should be
[Note the character ^M is a single character, which should be input as in Unix and in windows/DOS]
January 21st, 2006 at 3:33 am
Sorry AGAIN for the wrong HTMLized result, should be
[Note the character ^M is a single character, which should be input as <CTRL+V><CR> in Unix and <CTRL+Q><CR> in windows/DOS]
March 8th, 2007 at 4:57 pm
In vim7, you could also type
:vim[grep] /pattern/%
It does work also