全域代換

當你在編輯一份文件時,有時候可能會發現有一個名詞或單字必須被修改, 這時候你可能必須要修改整個文件中出現這的名詞或單字的地方, 這個時候你可以用全域代換來完成。

代換的指令是 s/pattern1/pattern2/, 這個指令要在 line mode 使用。 Vi 會將 pattern1 取代為 pattern2Pattern 翻譯成中文是樣式, 用 pattern 而不用 string﹝字串﹞的理由讀者很快會知道。

當你要代換文字時,你必須要先指定列數,當你下指令 1,$s/student/teacher/, vi 會把整份文件的 student 取代成 teacher。 但是這樣還不夠,這個指令只會把每一列的第一個 student 取代成 teacher , 如果一列中有兩個 student 的話,那只有第一個 student 會被代換成 teacher。 如果你是要把整份文件的 student 代換成 teacher, 那你的指令應該是 1,$s/student/teacher/g。 放在指令尾巴的 g 是全域﹝global﹞的意思,加上這個指令, 不管你一列中出現幾次 student,全部會代換成 teacher。

當你在作全域代換時一定要小心,特別是只代換一個字的時候, 常常會發現有些不想代換的字被代換。 例如你下指令 1,$s/行/列/g,這個指令為把文章裡的「行」代換成「列」, 所以「執行」會變成「執列」,這就不是我們想要的結果。 為了小心起見,我們可以再加一個指令 c(confirm), 這樣 vi 在每次代換之前就會先詢問是否要代換, 所以上面的指令可以改成 1,$s/行/列/gc

Regular expression

現在把重點放到 pattern,也就是樣式。 在前面有說過,vi 會把 patter1 代換成 pattern2。 但是或許你會發現,有幾個符號會出現一些錯誤, 這些符號大概有 .*^$\[] 等。這是因為 vi 對字串的搜尋是支援 regular expression 的。 Regular expression,翻譯作「規則字串」,是 unix 定下的一種規則。 當你在搜尋字串時, 只要依照 regular expression 告訴程式你要尋找的字串大概是什麼樣子, 程式就會將符合條件的字串找出來。 而上述的那些符號就是 regular expression 使用的符號, 所以 vi 會用不同的意義解釋這些符號。

如果你希望 vi 用原來的意義解釋那些符號, 只要在前面加上 \﹝跳脫字元﹞就行了。 例如你要代換「\」成「*」,就下指令 1,$s/\\/*/g。 在 pattern2 的 * 前面不加 \ 是因為 pattern2 不是搜尋用的, 所以規則和 pattern1 不一樣。

現在我們了了解一下用在 regular expression 的符號代表什麼意義:

看到這裡,你會發現上面介紹的 regurlar expression 都是用在 pattern1, 沒有一個能用在 pattern2。接下來要介紹的就是用在 pattern2 的語法。

其他的指令

現在 regular expression 介紹到這裡,接著要再介紹一些跟代換有關的指令。

直接下指令 s 會重複上一個代換。 例如先下指令 110s/a/b/g,再下指令 s, 就等於指令 s/a/b/﹝注意,沒有 g﹞。

在 command mode 下按【 & 】就等於 line mode 下的 s, 可以少按兩個按鍵。不過無法指令列數,也不能在後面加 g

在前面的代換指令中,尾巴大部分都跟著 g(global), 其實 g 還有其他的用法。 當你下指令 g/bgs 時,vi 會找到所有含有 bgs 的列, 並且全部印出來。 所以我們也可以下指令 g/bgs/d, 含有 bgs 的列會全部被刪除。 這是一種指定列數的方法,即使這些列不連續也會被 vi 接受。

用上述的方式,我們可以這樣下指令 g/bgs/s/heresy/shann/g, 這個指令會找出所有包含 bgs 的列, 然後把這些列的 heresy 換成 shann,其他不包含 bgs 的列的 heresy 則保持不動。

全域代換的基本指令大致介紹完畢,剩下的就是應用。 這方面的組合可以說有無窮多,只要你自己覺得方便就行了。 我沒提到的細節,就是重複上一個代換。 我認為少打那幾個字差不了多少。 如果要一列一列修改,那乾脆用 command mode 還比較快。

[ 前一節 ]‧[ 後一節 ]‧[ 回目錄 ]


製作人、
修改記錄
李易霖 (02/8/19) ---