2010年3月10日 星期三

vim的expression與substitute配合運作

vim強就強在可以對文字檔案本身,做有規則性的動作,像是同時在行首加入某一個特定的字串、找到某一個pattern,則執行某一個取代的動作。

另外,vim本身內建了很多function,透過expression與substitute結合起來,真的是天下無敵啊~可以不需要用到外部指令(當然有外部指令更好,就當作備用嘛~)

例如:
getline({lnum} [, {end}])
可以取得目前文件內容的第lnum行的資料。

input({prompt} [, {text} [, {completion}]])
可以讓使用者輸入資料

inputdialog({prompt} [, {text} [, {cancelreturn}]])
可以讓使用者透過跳出的視窗輸入資料

put
把字串放到文章中

line ({expr})
取得行數
Q: 取得目前指標的行數
line(".")
Q: 取得目前檔案最後一行的行數
line("$")
Q: 取得選取區塊的第一行行數
line("'<")
Q: 取得選取區塊的最後一行行數
line("'>")

submatch({nr})
而 submatch(0) 則是用來表示前面所尋找的整個字串(pattern),而submatch(1)的話,則用來表示第一個以 \(…\) 夾起來的子字串。

substitute({expr}, {pat}, {sub}, {flags})
在{expr}尋找{pat}並且用{sub}取代

假設這裡有一個文章,內容為
article.txt
I work hard,
I try to work smart.
Can I accomplish it?


Q: 如何在文章的內容每一行前面,加入行數
A: :%s/^/\=line(".") . "\. "/
解釋:
尋找^,也就是開頭字元,一般來說,這是看不到的!
要在substitute後面使用expression則必需使用\=
原文: When the substitute string starts with "\=" the remainder is interpreted as an
expression.
而line(".")上面說過了,就是表示目前指標的行數
而後面又有一個「.」我是把它想成連接的功用,與後面"\. "連接起來

Q: 如何把I改為You
A: %s/\<I\>/You/g
解釋:
\<I\>是表示我要找的就是一個單字I而已,而accomplish其中的i就不會被我取代掉,不然accomplish會被取代為accomplYoush

Q: 如何透過expression的方式,在I後面加上and you
A: %s/\<I\>/\=submatch(0) . " and you"/
解釋:
submatch(0)就是表示前面所找到的符合的字串
.是表示連接後面字串的動作的動作

Q: 如何同時在最前面加入行號,並且同時把I改為I and you
A: %s/\(.*\)\(\<I\>\)\(.*\)/\=line(".") . "\. " . submatch(1) . submatch(2) . " and you" . submatch(3)/

[2010.03.28 補充]
Q: 要如何行號補0,像是1就印001,2是002,而10就是010,這樣排版才會漂亮
A: :%s/^/\=printf("%03d ",line("."))/g

[2015.02.02 補充]
Q: 直接在14行到145加入index,
14是1.
15是2.
...
145行是132.
A: 14,145s/^/\=printf("%d. ",line(".") - 13)/g

參考資料:
vim 小技巧 : 行數的顯示與利用

沒有留言: