Linux shell 之 sed 命令詳解 第三部分
Linux shell 之 sed 命令詳解 第三部分
目錄:
五、修改行
六、轉換命令
七、回顧列印
八、使用 sed 處理檔案
五、修改行
修改( change)命令允許修改資料流中整行文字的內容。它跟插入和附加命令的工作機制一樣,你必須在sed命令中單獨指定新行。
1 sed '3c\
2 > This is a changed line of text.' data4.txt
3 This is line number 1
4 This is line number 2
5 This is a changed line of text.
6 This is line number 4
7 This is line number 5
8 $
在這個例子中,sed 編輯器會修改第三行中的文字。也可以用文字模式來定址。
1 $ sed '/number 3/c\
2 > This is a changed line of text.' data4.txt
3 This is line number 1
4 This is line number 2
5 This is a changed line of text.
6 This is line number 4
7 This is line number 5
8 $
文字模式修改命令會修改它匹配的資料流中的任意文字行。
1 $ sed '/number 1/c\
2 > This is a changed line of text.' data5.txt
3 This is a changed line of text.
4 This is line number 2.
5 This is line number 3.
6 This is line number 4.
7 This is line number 5.
8 This is line number 6.
9 This is a changed line of text.
10 This is text you want to keep.
11 This is the last line in the file.
12 $
你可以在修改命令中使用地址區間,但結果未必如願。
1 $ sed '2,3c\
2 > This is a new line of text.' data5.txt
3 This is line number 1.
4 This is a new line of text.
5 This is line number 4.
6 This is line number 5.
7 This is line number 6.
8 This is line number 1 again.
9 This is text you want to keep.
10 This is the last line in the file.
11 $
sed 編輯器會用這一行文字來替換資料流中的兩行文字,而不是逐一修改這兩行文字。
六、轉換命令
轉換(transform)命令(y)是唯一可以處理單個字元的 sed 編輯器命令。轉換命令格式如下。
[address]y/inchars/outchars/
轉換命令會對 inchars 和 outchars 值進行一對一的對映。inchars 中的第一個字元會被轉換位 outchars 中的第一個字元,第二個字元會被轉換成 outchars 中的第二個字元。這個對映過程會一直持續到處理完指定字元。如果 inchars 和 ouchars 的長度不同,則 sed 編輯器會產生一條錯誤訊息。
1 $ sed 'y/123/789/' data5.txt
2 This is line number 7.
3 This is line number 8.
4 This is line number 9.
5 This is line number 4.
6 This is line number 5.
7 This is line number 6.
8 This is line number 7 again.
9 This is text you want to keep.
10 This is the last line in the file.
11 $
如你在輸出中看到的,inchars 模式中指定字元的每個例項都會被替換成 outchars 模式中相同位置的那個字元。
轉換命令是一個全域性命令,也就是說,它會在文字行中找到的所有指定字元自動進行轉換,而不會考慮它們出現的位置。
1 $ echo "This 1 is a test of 1 try." | sed 'y/123/456/'
2 This 4 is a test of 4 try.
3 $
sed 編輯器轉換了在文字行中匹配到的字元 1 的兩個例項。你無法限定只轉換在特定地方出現的字元。
七、回顧列印
前面寫過使用 p 標記和替換命令顯示 sed 編輯器修改過的行。另外有 3 個命令也能用來列印資料流中的資訊:
⭐ p 命令用來列印文字行;
⭐等號( =)命令用來列印行號;
⭐l(小寫的L)命令用來列出行。
1、列印行
跟替換命令中的 p 標記類似, p 命令可以列印 sed 編輯器輸出中的一行。如果只用這個命令,也沒什麼特別的。
1 echo 'this is a test' | sed 'p'
2 this is a test
3 this is a test
4 $
它所做的就是列印已有的資料文字。列印命令最常見的用法是列印包含匹配文字模式的行。
1 $ cat data4.txt
2 This is line number 1
3 This is line number 2
4 This is line number 3
5 This is line number 4
6 This is line number 5
7 $
8 $ sed -n '/number 3/p' data4.txt
9 This is line number 3
10 $
在命令列上用-n選項,你可以禁止輸出其他行,只打印包含匹配文字模式的行。
也可以用它來快速列印資料流中的某些行。
1 $ sed -n '2,3p' data4.txt
2 This is line number 2
3 This is line number 3
4 $
如果需要在修改之前檢視行,也可以使用列印命令,比如與替換或修改命令一起使用。可以建立一個指令碼在修改行之前顯示該行。
1 $ sed -n '/3/{
2 > p
3 > s/line/tag/p
4 > }' data4.txt
5 This is line number 3
6 This is tag number 3
7 $
8 $
9 $
10 $
11 $ sed -n '3{
12 p
13 s/line/tag/p
14 }' data4.txt
15 This is line number 3
16 This is tag number 3
17 $
sed 編輯器命令會查詢包含數字3的行,然後執行兩條命令。首先,指令碼用 p 命令來打印出原始行;然後它用 s 命令替換文字,並用 p 標記打印出替換結果。輸出同時顯示了原來的行文字和新的行文字。
2、列印行號
等號命令會列印行在資料流中的當前行號。行號由資料流中的換行符決定。每次資料流中出現一個換行符, sed 編輯器會認為一行文字結束了。
1 $ cat data1.txt
2 the quick brown fox jumps over the lazy dog.
3 The quick brown fox jumps over the lazy dog.
4 The quick brown fox jumps over the lazy dog.
5 The quick brown fox jumps over the lazy dog.
6 $
7 zhengchuanyu@zhengchuanyu:~/reverse_xiaoyu$ sed '=' data1.txt
8 1
9 the quick brown fox jumps over the lazy dog.
10 2
11 The quick brown fox jumps over the lazy dog.
12 3
13 The quick brown fox jumps over the lazy dog.
14 4
15 The quick brown fox jumps over the lazy dog.
16 $
sed 編輯器在實際的文字行出現前列印了行號。如果你要在資料流中查詢特定文字模式的話,等號命令用起來非常方便。
1 $ sed -n '/number 4/{
2 > =
3 > p
4 > }' data4.txt
5 4
6 This is line number 4
7 $
利用 -n 選項,你就能讓 sed 編輯器只顯示包含匹配文字模式的行的行號和文字。
3、列出行
列出( list)命令( l)可以列印資料流中的文字和不可列印的 ASCII 字元。任何不可列印字元要麼在其八進位制值前加一個反斜線,要麼使用標準C風格的命名法(用於常見的不可列印字元),比如 \t,來代表製表符。
1 $ cat data4.txt
2 This is line number 1
3 This is line number 2
4 This is line number 3
5 This is line number 4
6 This is line number 5
7 $
8 $ sed -n 'l' data4.txt
9 This is line number 1$
10 This is line number 2$
11 This is line number 3$
12 This is line number 4$
13 This is line number 5$
14 $
1 $ cat data6.txt
2 I love linux shell
3 $
4 $ sed -n 'l' data6.txt
5 I\tlove\tlinux\tshell$
6 $
製表符的位置使用 \t 來顯示。行尾的美元符表示換行符。如果資料流包含了轉義字元,列出命令會在必要時候用八進位制碼來顯示。
1 $ cat data10.txt
2 This line contains an escape character.
3 $
4 $ sed -n 'l' data10.txt
5 This line contains an escape character. \a$
6 $
data10.txt 文字檔案包含了一個轉義控制碼來產生鈴聲。當用 cat 命令來顯示文字檔案時,你看不到轉義控制碼,只能聽到聲音(如果你的音箱開啟的話)。但是,利用列出命令,你就能顯示出所使用的轉義控制碼。
八、使用 sed 處理檔案
替換命令包含一些可以用於檔案的標記。還有一些 sed 編輯器命令也可以實現同樣的目標,不需要非得替換文字。
1、寫入檔案
w 命令用來向檔案寫入行。該命令的格式如下:
[address]w filename
filename 可以使用相對路徑或絕對路徑,但不管是哪種,執行 sed 編輯器的使用者都必須有檔案的寫許可權。地址可以是 sed 中支援的任意型別的定址方式,例如單個行號、文字模式、行區間或文字模式。
下面的例子是將資料流中的前兩行列印到一個文字檔案中。
1 $ sed '1,2w test.txt' data4.txt
2 This is line number 1
3 This is line number 2
4 This is line number 3
5 This is line number 4
6 This is line number 5
7 $
8 $ cat test.txt
9 This is line number 1
10 This is line number 2
11 $
當然,如果你不想讓行顯示到 STDOUT 上,你可以用 sed 命令的 -n 選項。
如果要根據一些公用的文字值從主檔案中建立一份資料檔案,比如下面的郵件列表中的,那麼 w 命令會非常好用。
1 $ cat data11.txt
2 Blum, R Browncoat
3 McGuiness, A Alliance
4 Bresnahan, C Browncoat
5 Harken, C Alliance
6 $
7 $ sed -n '/Browncoat/w Browncoats.txt' data11.txt
8 $
9 $ cat Browncoats.txt
10 Blum, R Browncoat
11 Bresnahan, C Browncoat
12 $
sed 編輯器會只將包含文字模式的資料行寫入目標檔案。
2、從檔案讀取資料
瞭解瞭如何在 sed 命令列上向資料流中插入或附加文字。讀取( read)命令( r)允許你將一個獨立檔案中的資料插入到資料流中。
讀取命令的格式如下:
[address]r filename
filename 引數指定了資料檔案的絕對路徑或相對路徑。你在讀取命令中使用地址區間,只能指定單獨一個行號或文字模式地址。 sed 編輯器會將檔案中的文字插入到指定地址後。
1 $ cat data7.txt
2 I love linux shell
3 $ sed '$r data7.txt' data4.txt
4 This is line number 1
5 This is line number 2
6 This is line number 3
7 This is line number 4
8 This is line number 5
9 I love linux shell
10 $
sed 編輯器會將資料檔案中的所有文字行都插入到資料流中。同樣的方法在使用文字模式地址時也適用。
1 $ sed '/number 2/r data12.txt' data6.txt
2 This is line number 1.
3 This is line number 2.
4 This is an added line.
5 This is the second added line.
6 This is line number 3.
7 This is line number 4.
8 $
如果你要在資料流的末尾新增文字,只需用美元符地址符就行了。
讀取命令的另一個很酷的用法是和刪除命令配合使用:利用另一個檔案中的資料來替換檔案中的佔位文字。舉例來說,假定你有一份套用信件儲存在文字檔案中:
1 $ cat notice.std
2 Would the following people:
3 LIST
4 please report to the ship's captain.
5 $
套用信件將通用佔位文字 LIST 放在人物名單的位置。要在佔位文字後插入名單,只需讀取命令就行了。但這樣的話,佔位文字仍然會留在輸出中。要刪除佔位文字的話,你可以用刪除命令。結果如下:
1 $ sed '/LIST/{
2 > r data11.txt
3 > d
4 > }' notice.std
5 Would the following people:
6 Blum, R Browncoat
7 McGuiness, A Alliance
8 Bresnahan, C Browncoat
9 Harken, C Alliance
10 please report to the ship's captain.
11 $
現在佔位文字已經被替換成了資料檔案中的名單。