本文首先以一個簡單的sed命令應用示例,說明如何使用sed命令進行文本處理,接著從sed命令的用法、工作原理、行地址模式以及sed命令支持的腳本命令詳細介紹sed命令的用法。
一個完整的sed命令使用簡單示例
- <para>
- This is a test paragraph.
- <Figure Begin>
- 111111111111111101000000000000000000000000000000111111111111111111100000000
- 000000000000000000000000000000000001111111111111111111111111111111111111111
- 11111111111111111110000000000000000000
- <Figure End>
- <para>
- MOre lines of text to be found after the figure.
- These lines should print.
- /<para>/{
- N #讀入下一行,因為下一行為空行,
- c\ #使用下面的內容替換模式空間中的內容,之所以使用N命令,也是想把<para>下面的空行刪除
- .LP
- }
- /<Figure Begin>/,/<Figure End>/{ #匹配<Figure Begin>到<Figure End>行之間的內容
- w fig.test #將這部分中的當前模式空間中的內容寫入文件fig.test中,因為sed命令式按行讀取文件內容的
- /<Figure End>/i\ #在<Figure End>行前插入下面的內容
- .FG\
- <inset figure here>\
- .FE
- d #刪除匹配的行,即刪除模式空間中的內容,這樣模式空間中的這部分內容不會被輸出
- }
- /^$/d #刪除所有空行
- .LP
- This is a test paragraph.
- .FG
- <inset figure here>
- .FE
- .LP
- MOre lines of text to be found after the figure.
- These lines should print.
上面簡單演示了一個使用sed命令的實際例子,初學時看不懂沒有關系,只需知道大概是這么個流程,然后下面會詳細的解釋sed命令的用法。
sed命令用法
sed[選項] {腳本 | 腳本文件} [輸入文件],其中[ ]表示可選,{}表示必須。
首先將3個經常出現的選項解釋如下:
上面出現了sed命令的三個最基本最常見的參數選項,其意思如下表所示:
-n選項 | 抑制sed命令的默認輸出 |
-e選項 | 后接單引號包含的命令腳本,僅應用單個命令于輸入文件時適用 |
-f 選項 | 指定一個文件包含多個腳本命令 |
這幾個選項的使用模式大致如下:
sed -n -e 'cmd_script' input_file #注意,單引號擴住腳本命令
sed -f script_file input_file #將腳本命令寫入一個單獨的文件
其實,sed命令的選項并不是學習sed命令的主要內容,主要內容是對于sed命令腳本部分的學習。sed支持的腳本命令比較多,后面會詳細介紹該部分內容,介紹sed支持的腳本命令之前,先介紹一下sed命令執行的原理。
sed工作原理
下面以sed -f script_file input_file為例,其工作原理如下圖所示:
其中input_file表示處理文件,script_file表示腳本命令。
工作原理如下:
a) 首先將處理文件的第一行讀入模式空間。
b) 接著對模式空間中的這一行內容執行腳本命令中設置的命令,從上至下依次執行腳本命令中設置的命令。
c) 腳本命令執行完成后,輸出模式空間中的內容。
d) 清空模式空間中得內容,并讀入處理文件中得第二行內容,并重復b) 和 c) 步驟的內容,直至處理完文件中的所有內容。
苦逼的碼農可以查看圖片右上角的偽代碼,可能解釋得更加清晰一點。
下面先對幾個經常出現的名詞進行解釋:
模式空間
以上描述中出現了一個詞叫模式空間,下面對其進行解釋。由于sed命令的執行并不修改原始文件,也就是說輸入文件是什么,執行完sed命令后,輸入文件沒有變化,這么說來,肯定不能在輸入文件的基礎上對其進行編輯,所以需要一塊單獨的空間,用于轉存文件中得內容,然后進行處理并輸出。模式空間就是這么一塊轉存輸入文件內容的空間,并且sed命令一次讀入輸入文件中得一行內容到模式空間,使用sed命令支持的腳步執行處理完模式空間中得內容后,輸出處理完的結果并刪除模式空間中得內容,準備讀入下一行輸入文件中得內容。
多行模式空間
如上所述,模式空間每次讀入輸入文件中的一行進行處理,有時只讀入一行內容到模式空間對輸入文件的處理能力很有限,比如它很難處理一個在一行末尾處開始,并在下一行開始處結束的短語。而多行模式空間就是為了解決這個問題而提出的,他允許將模式空間中的內容從一行擴展到多行。具體內容在本文后面會有講解。
保持空間
模式空間是容納當前輸入行的緩沖區,而保持空間是預留的一部分緩沖區,用于臨時存儲模式空間中的內容。模式空間中的內容可以復制到保持空間,保持空間中的內容也可以復制回模式空間。具體內容在本文后面會有講解。
sed命令的行地址模式
sed命令支持的腳本命令
sed命令所支持的腳本命令很多,常見的腳本命令有s、d、p、n、i、a、c、y等。其中還包括與多行模式空間相關的N、D、P命令(均大寫)。與保持空間相關的h、H、g、G、x命令。
1. s命令(替換)
語法:[address]s/pattern/replacement/flags
解釋:替換命令應用于與address匹配的行(address的匹配見行地址模式一節),如果沒有指定address,就應用于與pattern匹配的所有行。
flags標注可能是以下幾種情況中得一種:
g: 對模式空間中所有出現匹配的情況均進行替換。沒有指定g時表示僅對第1次出現匹配的情況進行替換。
n: 1-512之間的一個數字,表示對當前模式空間中第n次出現所匹配部分的內容進行替換,其余所匹配部分的內容不變。
p: 打印模式空間中的內容。
w file: 將模式空間中的內容寫入file中。
換行符在計算機內部只是一個字符,所有正則表達式可以使用"\n"來匹配換行符。
replacement部分,下列字符具有特殊含義:
&: 用正則表達式匹配的內容進行替換。
\n: 匹配第n個子串,這個子串以前在pattern中使用"\("和"\)"指定。
\: 轉義字符,如上所述的&字符,在replacement中出現是就需要使用轉義字符。
例:
s/UNIX/\\s-&\\s0/g腳本將 on the UNIX OS 替換為 on the \s-UNIX\s0 OS,其中UNIX為正則表達式匹配的內容,替換replacement中的&字符。其中第一個"\"字符為轉義字符。
s!/usr/mail!/usr2/mail!g #定界符并不一定必須是"/",也可以選擇其他字符,如本例中使用"!"作為定界符。
有一個test.txt文件內容為first:second,現在想要將first和second替換位置。可以使用如下命令實現:
sed -e 's/\(.*\):\(.*\)/\2:\1/' test.txt #"\("、"\)"在pattern中指定了兩個子串,"\1"、"\2"表示匹配第1個和第2個子串。