vim替換命令


轉載:http://blog.csdn.net/glorin/article/details/6317098

 

替換(substitute)

:[range]s/pattern/string/[c,e,g,i]5.1

 

 

range 指的是範圍,1,7 指從第一行至第七行,1,$ 指從第一行至最後一行,也就是整篇文章,也可以 % 代表。還記得嗎? % 是目前編輯的文章,# 是前一次編輯的文章。
pattern 就是要被替換掉的字串,可以用 regexp 來表示。
string 將 pattern 由 string 所取代。
c confirm,每次替換前會詢問。
e 不顯示 error。
g globe,不詢問,整行替換。
i ignore 不分大小寫。

 

g 大概都是要加的,否則只會替換每一行的第一個符合字串。可以合起來用,如 cgi,表示不分大小寫,整行替換,替換前要詢問是否替換。 

 

vi/vim 中可以使用 :s 命令來替換字符串。以前只會使用一種格式來全文替換,今天發現該命令有很多種寫法(vi 真是強大啊,還有很多需要學習),記錄幾種在此,方便以后查詢。

:s/vivian/sky/ 替換當前行第一個 vivian 為 sky

:s/vivian/sky/g 替換當前行所有 vivian 為 sky

:n,$s/vivian/sky/ 替換第 n 行開始到最后一行中每一行的第一個 vivian 為 sky

:n,$s/vivian/sky/g 替換第 n 行開始到最后一行中每一行所有 vivian 為 sky

n 為數字,若 n 為 .,表示從當前行開始到最后一行

:%s/vivian/sky/(等同於 :g/vivian/s//sky/) 替換每一行的第一個 vivian 為 sky

:%s/vivian/sky/g(等同於 :g/vivian/s//sky/g) 替換每一行中所有 vivian 為 sky

可以使用 # 作為分隔符,此時中間出現的 / 不會作為分隔符

:s#vivian/#sky/# 替換當前行第一個 vivian/ 為 sky/

:%s+/oradata/apras/+/user01/apras1+ (使用+ 來 替換 / ): /oradata/apras/替換成/user01/apras1/

1.:s/vivian/sky/ 替換當前行第一個 vivian 為 sky

:s/vivian/sky/g 替換當前行所有 vivian 為 sky

2. :n,$s/vivian/sky/ 替換第 n 行開始到最后一行中每一行的第一個 vivian 為 sky

:n,$s/vivian/sky/g 替換第 n 行開始到最后一行中每一行所有 vivian 為 sky

(n 為數字,若 n 為 .,表示從當前行開始到最后一行)

3. :%s/vivian/sky/(等同於 :g/vivian/s//sky/) 替換每一行的第一個 vivian 為 sky

:%s/vivian/sky/g(等同於 :g/vivian/s//sky/g) 替換每一行中所有 vivian 為 sky

4. 可以使用 # 作為分隔符,此時中間出現的 / 不會作為分隔符

:s#vivian/#sky/# 替換當前行第一個 vivian/ 為 sky/

5. 刪除文本中的^M

問題描述:對於換行,window下用回車換行(0A0D)來表示,Linux下是回車(0A)來表示。這樣,將window上的文件拷到Unix上用時,總會有個^M.請寫個用在unix下的過濾windows文件的換行符(0D)的shell或c程序。

· 使用命令:cat filename1 | tr -d “^V^M” > newfile;

· 使用命令:sed -e “s/^V^M//” filename > outputfilename。需要注意的是在1、2兩種方法中,^V和^M指的是Ctrl+V和Ctrl+M。你必須要手工進行輸入,而不是粘貼。

· 在vi中處理:首先使用vi打開文件,然后按ESC鍵,接着輸入命令:%s/^V^M//。

· :%s/^M$//g

如果上述方法無用,則正確的解決辦法是:

· tr -d “/r” < src >dest

· tr -d “/015″ dest

· strings A>B

6. 其它

利用 :s 命令可以實現字符串的替換。具體的用法包括:

:s/str1/str2/ 用字符串 str2 替換行中首次出現的字符串 str1

:s/str1/str2/g 用字符串 str2 替換行中所有出現的字符串 str1

:.,$ s/str1/str2/g 用字符串 str2 替換正文當前行到末尾所有出現的字符串 str1

:1,$ s/str1/str2/g 用字符串 str2 替換正文中所有出現的字符串 str1

:g/str1/s//str2/g 功能同上

從上述替換命令可以看到:g 放在命令末尾,表示對搜索字符串的每次出現進行替換;不加 g,表示只對搜索

字符串的首次出現進行替換;g 放在命令開頭,表示對正文中所有包含搜索字符串的行進行替換操作。

里以編寫C語言程序為例, 假設,我們最終想完成的代碼如下:

#define BIT_MASK_1      (1 << 0)
#define BIT_MASK_2      (1 << 1)
#define BIT_MASK_3      (1 << 2)
#define BIT_MASK_4      (1 << 3)
#define BIT_MASK_5      (1 << 4)
#define BIT_MASK_6      (1 << 5)
#define BIT_MASK_7      (1 << 6)
#define BIT_MASK_8      (1 << 7)
#define BIT_MASK_9      (1 << 8)
#define BIT_MASK_10      (1 << 9)
#define BIT_MASK_11      (1 << 10)
#define BIT_MASK_12      (1 << 11)
#define BIT_MASK_13      (1 << 12)
#define BIT_MASK_14      (1 << 13)
#define BIT_MASK_15      (1 << 14)
#define BIT_MASK_16      (1 << 15)
#define BIT_MASK_17      (1 << 16)
#define BIT_MASK_18      (1 << 17)
#define BIT_MASK_19      (1 << 18)
#define BIT_MASK_20      (1 << 19)
#define BIT_MASK_21      (1 << 20)
#define BIT_MASK_22      (1 << 21)
#define BIT_MASK_23      (1 << 22)
#define BIT_MASK_24      (1 << 23)
#define BIT_MASK_25      (1 << 24)
#define BIT_MASK_26      (1 << 25)
#define BIT_MASK_27      (1 << 26)
#define BIT_MASK_28      (1 << 27)
#define BIT_MASK_29      (1 << 28)
#define BIT_MASK_30      (1 << 29)
#define BIT_MASK_31      (1 << 30)
#define BIT_MASK_32      (1 << 31)



我們不需要一行一行的去寫,只需要先寫好第一行,如下:

#define BIT_MASK_1      (1 << 0)


然后,我們回到Normal模式,在這一行上輸入“Y31p",拷貝此行,然后粘貼31次。這樣,我們得到總共32行上面的內容。
現在使用"V31j"命令選中這32行,然后使用兩次替換命令:

:'<,'>s/BIT_MASK_/zs/d*/ze//=line(".") - line("'<") + 1
:'
<,'>s//zs/d*/ze)$//=line(".")-line("'<")


這樣,我們就得到了我們想要的結果。
這種方式還可以用於數組下標的自動增加,以及文本的章節自動編號等功能。只要你能夠用正則表達式准確的定位出你想要自動編號的的數字,那么就可以使用這種方法來自動編號。

上面,我們使用了兩條VIM替換命令,下面詳細剖析一下這兩條命令。

以第一條命令為例,第二條命令和第一條命令類似:

:'<,'>s/BIT_MASK_/zs/d*/ze//=line(".") - line("'<") + 1

這條命令在我們選中的區域內進行替換,查找以“BIT_MASK_”開頭,后面跟任意多個數字的字符串,並把匹配位置放在數字上,然后使用后面表達式計算出來的數字替換這些匹配的數字。
下面是這條命令中每個元素的含義:

'<,'>        我們所選中的區域 (:help '<,:help '> )
s            在選中的區域中進行替換 (:help :s )
/zs          指明匹配由此開始 (:help 
//zs )
/d
*          查找任意位數的數字 (:help //d )
/ze          指明匹配到此為止 (:help 
//ze )
/=           指明后面是一個表達式 (:help :s/= )
line(
".")    當前光標所在行的行號 (:help line() )
line(
"'<"  我們所選區域中第一行的行號 (:help line() )


'<”和“'>”是我們使用了“v”,“V”命令選中一個visual區域后,VIM設置的標記,分別用來標識visual區域的開始和結束。
BIT_MASK_/zs/d*/ze”是一個正則表達式,用來查找以“BIT_MASK_”開頭,后面跟任意多個數字的字符串。其中“/zs”、“/ze”用來指定匹配的開始和結束位置,因為我們只打算替換“BIT_MASK_0”中的數字,所以在查找時只把匹配區域置在數字上。
由於我們的替換操作要把不同行的數字替換成不同的值,所以在這里需要使用一個表達式來計算出替換后的值。當“:s”命令的替換字符串是以“/=”開頭時,表明使用一個表達式計算的結果進行替換。我們這里的表達式就是“line(".") - line("'<") + 1”,其中“line()”函數用來獲得行號,它可以獲得當前行的行號,以及指定的標記(mark)所在的行號。“line(“.”)”用來獲得當前光標所在行的行號,“line(“’<”)”則用來獲得“'<標記所在行的行號。這兩個行號的差加上1就是我們想替換的值。

上面,我們使用VIM的替換功能,實現高效的代碼編寫。本文將介紹另外一種方法,實現相同的功能。

我們先看例子:

我們要把上面代碼中括號中的數字,替換成由0開始的一個順序遞增序列,例如:

     UniqueID2       = lview.focusedItem.subItems.opIndex(0).text;
     Parent          
= lview.focusedItem.subItems.opIndex(1).text;
     Children        
= lview.focusedItem.subItems.opIndex(2).text;
     ……

實現以上需求,除了用前面介紹的方法外,還可以用下面的命令:

:let n=0 | g/opIndex(/zs/d/+/s///=n/|let n+=1

這條命令同上一篇介紹的命令類似,它也使用了VIM的替換功能和表達式,不同之處在於它並不需要事先選中替換區域,因為它沒有使用”line()”函數來計算當前位置的偏移,而是直接使用變量來進行賦值。
下面簡單講解一下這條命令各個組成元素:

let          為變量賦值 (:help let )
|            用來分隔不同的命令 (:help :bar )
g            在匹配后面模式的行中執行指定的ex命令 (:help :g )
/zs          指明匹配由此開始 (:help 
//zs )
/d/
+         查找1個或多個數字 (:help //d )
           對匹配模式進行替換 (:help :s )
/=           指明后面是一個表達式 (:help :s/= )

所以,這條命令的執行過程為:
1.    給變量n賦值為0;
2.    查找模式” opIndex(/zs/d/+”,使用變量n的值替換匹配的模式字符串;
3.    給變量n加1;

需要說明一下”|”,它用來分隔不同的命令。
另外,在substitute命令中,如果省略匹配模式字符串,它會使用之前定義的匹配模式字符串,在本例中就是由”global”命令定義的”opIndex(/zs/d/+”。

除了上面介紹的方法外,還有一個VIM插件專門實現數字、日期等的增、減,可以在下面的網址下載此插件:
http://vim.sourceforge.net/scripts/script.php?script_id=670

http://mysite.verizon.net/astronaut/vim/index.html#VISINCR


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM