10 個你必須掌握的超酷 VI 命令技巧

oschina發表於2013-06-28

  大部分Linux開發者對vi命相當熟悉,可是遺憾的是,大部分開發者都只能掌握一些最常用的Linux vi命令,下面介紹的10個vi命令雖然很多不為人知,但是在實際應用中又能讓你大大提高效率。

  在使用vi 編輯器時—無論是初次使用的使用者,還是有經驗的使用者—大多數人往往只掌握核心命令集,這些命令可以執行最常用的功能:導航或儲存檔案;插入、更新、刪除或搜尋資料;退出但不儲存修改。

  但是,vi 編輯器極其強大,特性和功能非常豐富。即使在多年使用vi 之後,您仍然可能會發現有不知道的新命令。本文討論的命令就屬於不太為人所知的命令,但是它們可以簡化您目前採用的操作方法,讓您的工作方式更高效,或者 讓您能夠完成原來不知道可以用vi 完成的操作。

  開啟和關閉行號

  vi 編輯器的許多選項可以控制編輯會話的外觀和感覺。使用 :set 命令修改vi 中的會話設定。按 Escape 鍵進入命令模式之後,可以使用 :set all 命令顯示選項和設定的列表。可以設定的選項之一是 number,它的作用是開啟和關閉行號

#

# Internet host table

#

::1     localhost

127.0.0.1       localhost       loghost

192.168.0.6     centos5

192.168.0.10    appserv

192.168.0.11    webserv

192.168.0.12    test

192.168.0.5     solaris10       # Added by DHCP

~

~

~

:set number

這個vi命令 在當前編輯的檔案中的每個記錄上顯示行號。讓vi 進入命令模式之後,可以輸入 :set number 並按回車來開啟行號

       #

# Internet host table

#

::1     localhost

127.0.0.1       localhost       loghost

192.168.0.6     centos5

192.168.0.10    appserv

192.168.0.11    webserv

192.168.0.12    test

192.168.0.5     solaris10       # Added by DHCP

  可以使用 :set nonumber 命令關閉行號。還可以使用這個命令和 :set number 命令的簡寫,即 :set nu 和 :set nonu。如果需要快速計算要用vi 函式處理的行數,顯示行號會非常有幫助。當行數很多,可能跨多個螢幕時,行號尤其有用。另外,有時候您知道要處理的行範圍,但是需要查明要在vi 命令中使用的初始和結束行號。如果希望每次進入vi 會話時都顯示行號,那麼在主目錄中的.exrc 檔案中新增 set number 行。

  自動縮排

  在用某些程式設計語言編寫程式碼時,縮排是樣式的重要部分,可以確保程式碼的可讀性更好。如果需要,可以在vi 編輯器中根據程式語言的樣式設定自動縮排。使用 autoindent 開啟或關閉自動縮排.

#!/bin/ksh

#

#

for file in /etc/*

do

if [[ -f ${file}  ]] ; then

echo “${file} is a file”

 

~

~

~

~

~

:set autoindent

  在此之後,如果在一行的開頭輸入空格或製表符,那麼後續的新行將會縮排到相同的位置。在命令模式下,輸入 :set autoindent,然後按回車開啟自動縮排。通過設定 shiftwidth 確定縮排級別。例如,:set shiftwidth=4 把每級縮排設定為四個空格。

#!/bin/ksh

#

#

for file in /etc/*

do

if [[ -f ${file}  ]] ; then

echo “${file} is a file”

elif [[ -d ${file} ]] ; then

echo “${file} is a directory”

fi

done

~

~

:set shiftwidth=4

  在命令模式下,可以使用>> 命令讓現有的一行增加一級縮排,使用<< 命令減少一級縮排。在這些命令前面加上一個整數,即可讓多行增加或減少一級縮排。例如,把遊標放在清單 4 中第 6 行的開頭,進入命令模式之後,輸入 5>> 就會讓下面五行增加一級縮排。

#!/bin/ksh

#

#

for file in /etc/*

do

if [[ -f ${file}  ]] ; then

echo “${file} is a file”

elif [[ -d ${file} ]] ; then

echo “${file} is a directory”

fi

done

~

~

  可以使用 :set noautoindent 命令關閉自動縮排。還可以使用這個命令和 autoindent 命令的簡寫,即 :set ai 和 :set noai。還可以使用 :set ai sw=4 在一個命令中開啟縮排並設定縮排級別。如果希望每次啟動vi 會話時都啟用自動縮排並把縮排級別設定為四個空格,那麼在主目錄中的.exrc 檔案中新增 set ai sw=4 行。

  在搜尋時不區分大小寫

  如您所知,在 UNIX®中執行搜尋時,模式匹配是區分大小寫的。但是,如果希望vi 不區分大小寫,那麼可以使用 :set ignorecase 命令。使用 :set noignorecase 恢復區分大小寫。還可以使用簡寫(:set ic 和 :set noic)。如果希望每次進入vi 會話時都啟用不區分大小寫的搜尋,那麼在主目錄中的.exrc 檔案中新增 set ignorecase 行。

  複合搜尋

  在vi 中,可以使用/命令搜尋字串,這需要以字面字串或正規表示式的形式指定要匹配的模式。例如,要想在檔案中搜尋單詞 echo,只需進入命令模式,輸入/echo,然後按回車。這個命令會找到清單 6 所示檔案的第 3 行的第一個單詞。

       #!/bin/ksh

#

echo “Starting”

file=${1}

echo ${file}

if [[ ${file} = 1 ]] ; then

((file=${file}+1))

echo “Adding one gives ” \

${file}

fi

echo “Ending”

exit

  可以使用簡單的正規表示式指定尋找包含某一單詞而且後面有另一個單詞的行。例如,要想尋找包含字串 echo、後面有零個或更多字元、之後是字串 file 的第一行,應該使用/echo.*file。在清單 6 所示的檔案中,這個命令會找到第 6 行的第一個單詞。

  但是,只有這兩個字串出現在同一行上,這個命令才認為是匹配的。如果希望搜尋出現在另一個模式或字串後面的某個模式或字串,不管這兩個模式或 字串是否在同一行上,那麼可以指定由分號(;)分隔的兩個搜尋命令,從而執行復合搜尋。例如,要想搜尋出現在字串{file}+1 後面的字串 echo,應該使用/{file}+1/;/echo/。在清單 6 所示的檔案中,這個命令會找到第 10 行的第一個單詞。複合搜尋對於尋找程式碼中出現在另一個命令後面的某個命令尤其有用—例如,在設定某個變數之後呼叫函式的地方。

  重放搜尋模式

  當在檔案中搜尋要替換的模式時,可以讓vi 把要匹配的任何模式儲存在緩衝區中;然後,在執行替換時,可以用緩衝區引用號重放它們。方法是把模式放在 \(和 \)之間,這會指示vi 把模式放在編號的緩衝區(1 到 9)中。在執行替換時,可以用緩衝區引用號 \1 到 \9 引用這些緩衝區。

  例如,假設要在清單 7 所示的檔案中搜尋以單詞 Martin 開頭的行並對每個匹配新增字首 Mr 和字尾 Wicks,那麼進入命令模式,輸入vi 命令 :%s/^\(Martin\)/Mr \1 Wicks/g,然後按回車。

Martin is an IT consultant. Martin likes

snowboarding and mountain biking. Martin has

worked on UNIX systems for over 15 years. Martin also

worked for many years before that on mainframes.

Martin lives in London.

~

~

~

~

:%s/^\(Martin\)/Mr \1 Wicks/g

  下面把這個命令分解開解釋一下:

  :%s —指示vi 執行替換。

  /—模式分隔符。

  ^\(Martin\)—尋找以字串 Martin 開頭的行並把這個字串儲存在緩衝區 1 中。

  /—模式分隔符。

  Mr \1 Wicks —把找到的字串替換為字串 Mr,加上緩衝區 1 中的內容,再加上字串 Wicks。

  /—模式分隔符。

  g —全域性修改(即修改所有匹配的地方)

  在搜尋和替換字串中都可以使用緩衝區引用。

Mr Martin Wicks is an IT consultant. Martin likes

snowboarding and mountain biking. Martin has

worked on UNIX systems for over 15 years. Martin also

worked for many years before that on mainframes.

Mr Martin Wicks lives in London.

~

~

~

~

:%s/^\(Martin\)/Mr \1 Wicks/g

  書籤

  可以讓vi 在檔案中的特定位置放上書籤。方法是按 Escape 鍵,再按 M 鍵,然後輸入另一個表示書籤引用的字母表字元。因此,最多可以有 26 個書籤,分別名為 a 到z。要返回到上一書籤,按 Escape 鍵,再按反撇號(`),然後輸入書籤引用字元。

  例如,按 Escape 之後按 M 和 A 鍵,就會把當前遊標位置儲存在書籤 a 中。在編輯會話中,以後希望返回到這個遊標位置時,只需按 Escape,然後輸入 `A。可以使用雙反撇號(“)命令在當前書籤和前一個書籤之間切換。

  查詢、更新、查詢下一個、重複

  在vi 編輯器中,最有用的搜尋/替換特性之一是查詢與某個模式匹配的字串,更新它,然後繼續搜尋下一個匹配的字串,然後選擇是否以相同方式更新它。這與 Microsoft® Word 中的查詢下一個/替換功能很相似。您可能已經知道可以在vi 中搜尋字串模式,方法是進入命令模式,輸入/search_pattern(其中的 search_pattern 是字串或正規表示式),然後按回車。這樣做就會找到與指定的模式匹配的第一個字串。在此之後,可以在找到的文字上執行任何操作。例如,按 Escape,再按 C 和 W 鍵,再輸入更多文字,就會把找到的字串替換為另一個單詞。

  要想快速地找到與模式匹配的下一個地方,應該按 Escape,然後按 N 鍵。在找到下一個匹配時,可以使用點號鍵(.)在這個位置重複最近的文字操作,比如前一個示例中使用的修改單詞(cw)操作。然後,可以使用這些鍵繼續尋 找其他匹配(n)並選擇重複文字操作(.),操作方式與使用 Word 中的查詢下一個/替換功能很相似。

  切換大小寫

  在vi 中,可以切換遊標下的字母字元的大小寫,方法是按 Escape,然後按波浪號鍵(~)。這會在小寫和大寫之間來回切換。按著這個鍵,移動遊標經過行中的每個字元,就會切換遇到的每個字母字元的大小寫。可 以在波浪號前面輸入一個數字,表示希望改變多少個字母字元的大小寫。

  篩選

  您可能知道,在vi 中按 Escape,輸入 :!command(其中的 command 是要執行的 UNIX 命令),然後按回車,就可以在 shell 中執行命令。例如,:!pwd 顯示編輯會話當前的工作目錄。

  但是,還可以把檔案的一部分作為標準輸入傳送給 UNIX 命令,並用產生的輸出替換編輯緩衝區中的相同部分。例如,如果希望在vi 會話內對清單 9 所示的整個檔案進行排序,可以按 Escape,輸入 :1,$!sort 並按回車,這讓vi 把從第一行到檔案末尾($)的所有內容傳遞給 sort 命令,用輸出替換指定的部分。

  另外,還可以在 shell 命令前面加上從當前遊標位置開始希望操作的行數。方法是按 Escape,然後輸入指定行數的數字,然後輸入兩個驚歎號(!!),最後輸入 UNIX 命令。

可以使用管道分隔符(|)把 UNIX 命令連線在一起,從而在vi 會話中執行復雜強大的篩選。例如,假設要把當前vi 會話的編輯緩衝區中的檔案內容替換為每行的第一個空格分隔的欄位,按升序排序並轉換為大寫,那麼在按 Escape 之後輸入:

:1,$!awk ‘{print $1}’ | sort | tr [:lower:] [:upper:]

  儲存部分內容

  可以儲存當前編輯的檔案的部分內容,方法是按 Escape,然後輸入 :start,endw file,其中的 start 是當前檔案中要儲存的第一行,end 是要儲存的最後一行,w表示希望寫到另一個檔案中(或者覆蓋現有的檔案),file 是指定的部分要儲存到的檔案。對於最後一行,可以使用$表示檔案的末尾。可以在w後面使用兩個大於號(>>)表示希望把內容附加到檔案中而不 是覆蓋檔案。清單 12 中的示例把第 6 到第 9 行(含)附加到檔案/tmp/newfile 中。

       #

# Internet host table

#

::1     localhost

127.0.0.1       localhost       loghost

192.168.0.6     centos5

192.168.0.10    appserv

192.168.0.11    webserv

192.168.0.12    test

192.168.0.5     solaris10       # Added by DHCP

~

~

~

:6,9w >> /tmp/newfile

  結束語

  vi 編輯器是一個極其強大的工具,本文提供了一些技巧和訣竅,希望能夠幫助您更高效地編輯檔案。請記住,vi 還有更多不太為人所知的特性。祝工作愉快!

相關文章