Usr_12

Nvim 的 :help 頁面,由 產生,使用 原始碼tree-sitter-vimdoc 解析器。


VIM 使用者手冊 - 作者:Bram Moolenaar
聰明的小技巧
藉由組合數個指令,您可以讓 Vim 幾乎完成任何事情。本章將介紹一些有用的組合。這裡會用到前幾章介紹的指令,以及一些新的指令。
12.1 取代單字 12.2 將 "Last, First" 改成 "First Last" 12.3 排序列表 12.4 反轉行順序 12.5 計算單字數量 12.6 尋找 man page 12.7 修剪空白 12.8 尋找單字的使用位置
下一章:usr_20.txt 快速輸入命令列指令 前一章:usr_11.txt 從當機中復原 目錄:usr_toc.txt

取代單字

可以使用 substitute 指令將所有出現的單字替換成另一個單字
:%s/four/4/g
"%" 範圍表示在所有行中取代。結尾的 "g" 旗標會導致一行中的所有單字都被取代。如果您的檔案也包含 "thirtyfour",這將無法正確運作,它會被取代為 "thirty4"。為了避免這種情況,請使用 "\<" 項目來匹配單字的開頭
:%s/\<four/4/g
顯然,這在 "fourteen" 上仍然會出錯。使用 "\>" 來匹配單字的結尾
:%s/\<four\>/4/g
如果您正在程式設計,您可能想要取代註解中的 "four",但不取代程式碼中的 "four"。由於這很難指定,請加入 "c" 旗標,讓 substitute 指令提示您進行每個取代
:%s/\<four\>/4/gc

在多個檔案中取代

假設您想要在多個檔案中取代一個單字。您可以編輯每個檔案並手動輸入指令。使用錄製和播放會快得多。假設您有一個目錄,其中包含 C++ 檔案,所有檔案都以 ".cpp" 結尾。有一個名為 "GetResp" 的函數,您想要將其重新命名為 "GetAnswer"。
vim *.cpp 啟動 Vim,定義參數列表以包含所有 C++ 檔案。您現在位於第一個檔案中。qq 開始錄製到 q 暫存器 :%s/\<GetResp\>/GetAnswer/g 在第一個檔案中進行取代。 :wnext 寫入此檔案並移動到下一個檔案。 q 停止錄製。 @q 執行 q 暫存器。這將重播取代和 ":wnext"。您可以驗證這不會產生錯誤訊息。 999@q 在剩餘的檔案上執行 q 暫存器。
在最後一個檔案,您會收到錯誤訊息,因為 ":wnext" 無法移動到下一個檔案。這會停止執行,並且所有操作都已完成。
注意: 當回放錄製的序列時,錯誤會停止執行。因此,請確保錄製時不會收到錯誤訊息。
有一個問題:如果其中一個 .cpp 檔案不包含單字 "GetResp",您將收到錯誤並且取代將停止。為了避免這種情況,請在 substitute 指令中加入 "e" 旗標
:%s/\<GetResp\>/GetAnswer/ge
"e" 旗標告訴 ":substitute" 找不到匹配不是錯誤。

12.2 將 "Last, First" 改成 "First Last"

您有一個格式如下的名稱列表
Doe, John
Smith, Peter
您想要將其更改為
John Doe
Peter Smith
只需一個指令即可完成此操作
:%s/\([^,]*\), \(.*\)/\2 \1/
讓我們將其分解為幾個部分。顯然,它從 substitute 指令開始。"%" 是行範圍,代表整個檔案。因此,取代會在檔案中的每一行執行。substitute 指令的參數為 "/from/to/"。斜線分隔 "from" 模式和 "to" 字串。以下是 "from" 模式包含的內容
\([^,]*\), \(.*\)
第一個 \( \) 之間的部分匹配 "Last" \( \) 匹配除了逗號以外的任何字元 [^,] 任何次數 * 匹配 ", " 字面值 , 第二個 \( \) 之間的部分匹配 "First" \( \) 任何字元 . 任何次數 *
在 "to" 部分,我們有 "\2" 和 "\1"。這些稱為反向引用。它們參考模式中 "\( \)" 部分匹配的文字。"\2" 參考第二個 "\( \)" 匹配的文字,也就是 "First" 名稱。"\1" 參考第一個 "\( \)" 匹配的文字,也就是 "Last" 名稱。您可以在 substitute 指令的 "to" 部分中使用最多九個反向引用。"\0" 代表整個匹配的模式。在 substitute 指令中還有一些特殊的項目,請參閱 sub-replace-special

12.3 排序列表

在 Makefile 中,您經常會看到一個檔案列表。例如
OBJS = \
version.o \
pch.o \
getopt.o \
util.o \
getopt1.o \
inp.o \
patch.o \
backup.o
要排序此列表,請透過外部 sort 指令篩選文字
/^OBJS
j
:.,/^$/-1!sort
這會移至第一行,其中 "OBJS" 是該行的第一個內容。然後它會向下移動一行並篩選行,直到下一個空行為止。您也可以在 Visual 模式中選取行,然後使用 "!sort"。這更容易輸入,但是當行數很多時,會需要更多工作。結果如下
OBJS = \
backup.o
getopt.o \
getopt1.o \
inp.o \
patch.o \
pch.o \
util.o \
version.o \
請注意,每行結尾的反斜線用於表示該行繼續。排序後,這是錯誤的!位於結尾的 "backup.o" 行沒有反斜線。既然它已排序到另一個位置,就必須有反斜線。最簡單的解決方案是使用 "A \<Esc>" 加入反斜線。如果您確定最後一行後面有一個空行,則可以保留最後一行中的反斜線。這樣您就不會再遇到這個問題了。

12.4 反轉行順序

:global 指令可以與 :move 指令結合使用,將所有行移動到第一行之前,從而產生反轉的檔案。指令如下
:global/^/move 0
縮寫形式
:g/^/m 0
"^" 正規表示式匹配行的開頭(即使該行為空白)。:move 指令將匹配的行移動到虛擬的第零行之後,因此當前匹配的行將成為檔案的第一行。由於 :global 指令不會被更改的行號混淆,因此 :global 會繼續匹配檔案的所有剩餘行,並將每一行放在最前面。
這也適用於一系列行。首先移動到第一行上方,並使用 "mt" 標記它。然後將游標移動到範圍中的最後一行,並輸入
:'t+1,.g/^/m 't

12.5 計算單字數量

有時您必須撰寫文字,且單字數量有上限。Vim 可以為您計算單字數量。當您想要計算整個檔案中的單字數量時,請使用此指令
g CTRL-G
請勿在 g 之後輸入空格,這裡只是為了讓指令易於閱讀。輸出如下所示
Col 1 of 0; Line 141 of 157; Word 748 of 774; Byte 4489 of 4976
您可以看到您所在的單字位置 (748) 以及檔案中的單字總數 (774)。
當文字只是檔案的一部分時,您可以移動到文字的開頭,輸入 "g CTRL-G",移動到文字的結尾,再次輸入 "g CTRL-G",然後用您的腦袋計算單字位置的差異。這是一個很好的練習,但是有一種更簡單的方法。在 Visual 模式下,選取您要計算單字數量的文字。然後輸入 g CTRL-G。結果
Selected 5 of 293 Lines; 70 of 1884 Words; 359 of 10928 Bytes
如需其他計算單字、行和其他項目的方法,請參閱 count-items

12.6 尋找 man page find-manpage

在編輯 shell 腳本或 C 程式時,您正在使用一個指令或函數,並且想要找到它的 man page(這是 Unix 系統上的情況)。讓我們首先使用一種簡單的方法:將游標移動到您要尋找說明文字的單字上,然後按
K
Nvim 將對該單字執行 :Man。如果找到 man page,則會顯示它。您也可以使用 :Man 指令在 man page 上開啟一個視窗
:Man csh
您可以四處捲動,並且文字會被突出顯示。這可讓您找到您要尋找的說明文字。使用 CTRL-W w 跳至您正在工作的文字所在的視窗。若要在特定章節中尋找 man page,請先輸入章節編號。例如,若要查看第 3 章中關於 "echo" 的說明
:Man 3 echo
若要跳至另一個 man page,該頁面中的文字格式通常為 "word(1)",請在其上按 CTRL-]。其他 ":Man" 指令將使用相同的視窗。
若要顯示游標下單字的 man page,請使用此指令
K
例如,您想知道編輯此行時 "strstr()" 的傳回值
if ( strstr (input, "aap") == )
將游標移動到 "strstr" 上的某個位置,然後輸入 "K"。將開啟一個視窗以顯示 strstr() 的 man page。

12.7 修剪空白

有些人認為行尾的空格和定位字元是無用、浪費且醜陋的。若要移除每行結尾的空白,請執行以下指令
:%s/\s\+$//
使用行範圍 "%",因此這適用於整個檔案。":substitute" 指令匹配的模式是 "\s\+$"。這會尋找行尾 ($) 之前的一個或多個 (\+) 空白字元 (\s)。稍後將說明如何撰寫類似這樣的模式,請參閱 usr_27.txt。substitute 指令的 "to" 部分為空白:"//"。因此,它會取代為無,實際上是刪除匹配的空白。
另一個浪費空格的情況是將空格放置在定位字元之前。通常,可以刪除這些空格,而不會更改空白的數量。但並非總是如此!因此,您最好手動執行此操作。使用此搜尋指令
/
您看不到,但是此指令中在定位字元之前有一個空格。因此,它是 "/<Space><Tab>"。現在使用 "x" 刪除空格,並檢查空白的數量是否沒有改變。如果確實改變了,您可能需要插入一個定位字元。輸入 "n" 以尋找下一個匹配項。重複此步驟,直到找不到更多匹配項。

12.8 尋找單字的使用位置

如果您是 Unix 使用者,則可以結合使用 Vim 和 grep 指令來編輯所有包含給定單字的檔案。如果您正在處理程式,並且想要檢視或編輯所有包含特定變數的檔案,這將非常有用。例如,假設您想要編輯所有包含單字 "frame_counter" 的 C 程式檔案。若要執行此操作,請使用以下指令
vim `grep -l frame_counter *.c`
讓我們詳細看看這個指令。grep 指令會在檔案集合中搜尋指定的字詞。由於指定了 -l 參數,該指令只會列出包含該字詞的檔案,而不會印出符合的行。它搜尋的字詞是 "frame_counter"。實際上,這可以是任何正規表示式。(注意: grep 使用的正規表示式與 Vim 使用的正規表示式並不完全相同。)整個指令都用反引號 (`) 包圍。這會告訴 Unix shell 執行這個指令,並假裝結果是在命令列上輸入的。因此,grep 指令會執行並產生一個檔案列表,這些檔案會被放到 Vim 的命令列上。這會導致 Vim 編輯 grep 輸出的檔案列表。然後,您可以使用 ":next" 和 ":first" 等指令來瀏覽這些檔案。

尋找每一行

上面的指令只會找出包含該字詞的檔案。您仍然需要在檔案中找到該字詞。Vim 有一個內建的指令,可以用來在一組檔案中搜尋指定的字串。例如,如果您想在所有 C 程式檔案中找到所有 "error_string" 的出現次數,請輸入以下指令
:grep error_string *.c
這會使 Vim 在所有指定的檔案 (*.c) 中搜尋字串 "error_string"。編輯器現在會開啟第一個找到匹配項的檔案,並將游標定位在第一個匹配行上。要跳到下一個匹配行(無論它在哪個檔案中),請使用 ":cnext" 指令。要跳到上一個匹配項,請使用 ":cprev" 指令。使用 ":clist" 來查看所有匹配項及其位置。":grep" 指令使用外部指令 grep (在 Unix 上) 或 findstr (在 Windows 上)。您可以透過設定選項 'grepprg' 來更改此設定。
下一章:usr_20.txt 快速輸入命令列指令
版權:請參閱 manual-copyright vim:tw=78:ts=8:noet:ft=help:norl
主頁
指令索引
快速參考