【Linux 命令行與 shell 腳本編程大全】 19 初始 sed 和 gawk

導(dǎo)覽

sed 編輯器可以在讀取數(shù)據(jù)時對數(shù)據(jù)快遞的進(jìn)行各種處理操作,s 命令 可以替換文本,i 命令 可以插入文本,a 命令 可以追加文本,c 命令 可以修改文本,d 命令 可以刪除文本,y 命令 可以轉(zhuǎn)換文本,p 命令 可以打印文本,= 命令 可以打印行號,l 命令 可以打印 ASCII 字符,w 命令 可以輸出內(nèi)容到指定文件,r 命令 可以從指定文件讀取內(nèi)容。
sed 編輯器還支持 行尋址 ,以上大部分命令都支持使用行尋址的方式來靈活操作數(shù)據(jù)。

gawk 編輯器是根據(jù) awk 工具從 Unix 移植到 Linux 的 GNU 版本,雖然功能強(qiáng)大,但 Linux 默認(rèn)沒有安裝該工具,可以通過 yum install gawk 命令進(jìn)行安裝。gawk 編輯器提供的是一種編程語言,而不僅僅是編輯器命令。

19.1 文本處理

sed 和 gawk 實(shí)現(xiàn)的效果是:不進(jìn)入交互式編輯器,就可以實(shí)現(xiàn)自動格式化、插入、修改或刪除文件中的文本數(shù)據(jù)。

19.1.1 sed 編輯器

sed 編輯器簡稱 流編輯器( Stream Editor ) ??梢愿鶕?jù)命令來處理數(shù)據(jù)流中的數(shù)據(jù),這些命令可以直接從命令行輸入,也可以存在于指定文件中。

sed 編輯器會將所有命令與一行數(shù)據(jù)進(jìn)行匹配,匹配完畢后就自動讀取下一行數(shù)據(jù),并重復(fù)之前的操作,當(dāng)所有數(shù)據(jù)都讀取完畢后,命名才會終止。處理后的數(shù)據(jù)不會影響原文件,而是輸出到 STDOUT 。

sed 命令的基本格式是 sed option script file
option 中可用的選項(xiàng)如下圖:

image

19.1.1.1 在命令行定義編輯器命令

默認(rèn)情況下,sed 編輯器會將指定的命令應(yīng)用到 STDIN 上,這樣就可以直接將數(shù)據(jù)通過管道輸入到 sed 編輯器中進(jìn)行處理,效果如下:

[ttxie@41 part19]$ echo "This is a test" | sed 's/test/big test/'
This is a big test

在上圖中可以看到,echo 輸出的語句通過 | 管道傳入 sed 命令。在 sed 編輯器中使用了 s 命令,作用是用斜線之間指定的第二個文本替換第一個文本的內(nèi)容。

19.1.1.2 在命令行使用多個編輯器命令

要在 sed 編輯器的命令行模式中指定多個命令,使用 sed -e 命令即可,效果如下:

[ttxie@41 part19]$ echo "This is a test" | sed -e 's/test/big test/; s/This/That/'
That is a big test

在上圖中可以看到,添加 -e 指令后,只需要在多個命令之間使用分號隔開即可。需要注意的是,分號和命令末尾之間不能有空格。

如果不想使用分號,也可以使用 bash shell 的 次提示符 來分隔命令,效果如下:

[ttxie@41 part19]$ echo "This is a test" | sed -e '
> s/This/That/
> s/test/big test/'
That is a big test

在這種模式下,不需要在命令末尾添加分號。

19.1.1.3 從文件中讀取編輯器命令

使用 sed -f 命令即可從文件中讀取命令,效果如下:

[ttxie@41 part19]$ cat chang-name.sed
s/This/That/
s/test/big test/
[ttxie@41 part19]$ 
[ttxie@41 part19]$ echo "This is a test" |sed -f chang-name.sed 
That is a big test

在這種模式下,不需要在命令末尾添加分號。需要注意的是,.sed 后綴并不是強(qiáng)制的,只是為了避免 sed 編輯器的腳本文件和其他文件混淆。

19.1.2 gawk 編輯器

gawk 編輯器可以提供一個類編程環(huán)境,讓修改和重新組織文件中的數(shù)據(jù)變的更得心應(yīng)手。
Linux 中默認(rèn)沒有安裝 gawk 編輯器,如果當(dāng)前 Linux 中不存在該編輯器,需要使用 yum install gawk 命令進(jìn)行安裝。

使用 yum info gawk 命令可以查看該編輯器的詳細(xì)信息,源:installed 表示該編輯器已經(jīng)安裝到當(dāng)前 Linux 中。

image

也可以使用 whereis gawk 命令來查看當(dāng)前 Linux 中是否存在該編輯器。

image

gawk 編輯器是 Unix 中 awk 編輯器的 GNU 版本,該編輯器提供的是一種編程語言,而不僅僅是編輯器命令。
gawk 編輯器的強(qiáng)大之處在于可以編寫腳本,通過腳本來讀取文本行的數(shù)據(jù),對數(shù)據(jù)進(jìn)行處理后再顯示數(shù)據(jù),以及創(chuàng)建任意類型的輸出報告。

19.1.2.1 gawk 命令格式

gawk 編輯器的基本格式是 gawk option '{program}' file ,編輯器腳本必須使用單引號和花括號包裹。
option 中可用的選項(xiàng)如下圖:

image

19.1.2.2 從命令行讀取腳本

默認(rèn)情況下,gawk 編輯器從 STDIN 中接收數(shù)據(jù),效果如下:

[ttxie@41 part19]$ echo "my name is Rich" |gawk '{print "Hello world"}'
Hello world

當(dāng) gawk 命令接收到通過管道傳入的 echo 命令的輸出后,就在控制臺打印了 Hello World 語句。

如果直接在命令行中執(zhí)行 gawk 命令,那么該命令會一直等待用戶輸入,效果如下:

image.png

從上圖中可以看到,第一次執(zhí)行 gawk 命令后,手動輸入 1 并回車,控制臺打印了 Hello World 語句,再次輸入 2 并回車,控制臺再次打印了 Hello World ,以此類推。只要不手動退出,gawk 編輯器會一直監(jiān)聽用戶輸入。
在第一次執(zhí)行 gawk 命令的最后,可以清楚看到是使用 Ctrl + C 強(qiáng)制退出了 gawk 編輯器。其實(shí)該編輯器本身支持使用 Ctrl + D 退出監(jiān)聽,可以看到,第二次執(zhí)行 gawk 命令的最后,編輯器退出后并沒有顯示 Ctrl + C 的按鍵痕跡,因?yàn)檫@里正確使用了 Ctrl + D 來退出 gawk 編輯器。

19.1.2.3 使用數(shù)據(jù)字段變量

gawk 編輯器在處理文件數(shù)據(jù)時,會自動為 被字段分隔符分隔后的每個數(shù)據(jù) 分配一個變量,規(guī)則如下:

  • $0 表示整個文本行
  • $1 表示第一個數(shù)據(jù)字段
  • $2 表示第二個數(shù)據(jù)字段
  • 以此類推
    gawk 默認(rèn)的 字段分隔符任意的空白字符 ,例如空格或制表符,效果如下
image.png

從上圖中可以看到,每行數(shù)據(jù)中存在一個空格,通過該空格將每行的數(shù)據(jù)分為兩部分,gawk 編輯器使用 $1 成功獲取到每行的第一部分,并將其輸出。

可以使用 gawk -F 來修改字段分隔符,效果如下:

[ttxie@41 part19]$ gawk -F ":" '{print $1}' /etc/passwd |tail -n 5
gc
xlpan
dockerroot
xtcui
ttxie

上圖中使用 gawk -F : 命令將字段分隔符替換成了冒號,然后輸出了 passwd 文件中每行的第一個字段。由于輸出內(nèi)容過多,將輸出內(nèi)容通過管道傳入 tail -n 5 命令,最后只輸出 5 行數(shù)據(jù)。

19.1.2.4 在腳本中使用多個命令

gawk 編輯器允許將多個命令組合成一個完整的編輯器,和 sed 編輯器類似,對于多命令使用分號分隔即可,效果如下:

[ttxie@41 part19]$ cat gawk-data.txt 
my name is Rich
my name is Jack
[ttxie@41 part19]$ 
[ttxie@41 part19]$ gawk '{$3="not is"; print $0}' gawk-data.txt 
my name not is Rich
my name not is Jack

從上圖中可以看到,gawk 編輯器先將第三個字段改為 not is ,再使用 print $0 命令將整行數(shù)據(jù)輸出。

同樣的,也支持使用 次提示符 來編寫多個命令,效果如下:

[ttxie@41 part19]$ gawk '{
> $3="not is"
> print $0}' gawk-data.txt

my name not is Rich
my name not is Jack

19.1.2.5 從文件中讀取腳本

gawk 編輯器允許將腳本存儲到文件中,效果如下:

[ttxie@41 part19]$ cat change-data.gawk
{
$3="not is"
print $0
}
[ttxie@41 part19]$ 
[ttxie@41 part19]$ gawk -f change-data.gawk gawk-data.txt

my name not is Rich
my name not is Jack

從上圖中可以看到,在腳本中編寫多個命令非常方便,同時腳本命令外只需要使用花括號進(jìn)行包裹,不再需要使用單引號

19.1.2.6 在處理數(shù)據(jù)之前運(yùn)行腳本

gawk 編輯器可以控制腳本命令的運(yùn)行時機(jī)。默認(rèn)情況下,腳本命令會在讀取一行文本后就自動執(zhí)行一次。但可以通過 BEGIN 關(guān)鍵字 強(qiáng)制 gawk 在讀取數(shù)據(jù)之前執(zhí)行指定腳本。 ,效果如下:

[ttxie@41 part19]$ gawk '{print "Hello World"}'
1
Hello World

[ttxie@41 part19]$ gawk 'BEGIN {print "Hello World"}'
Hello World

從上圖中可以看到,默認(rèn)情況下,gawk 命令會在監(jiān)聽到用戶輸入后再輸出 Hello World 。但當(dāng)使用 BEGIN 關(guān)鍵字后,gawk 命令直接就輸出了 Hello World ,不再等待用戶輸入。

通過這種方式,可以為輸出內(nèi)容準(zhǔn)備一個通用的顯示頭信息,效果如下:

[ttxie@41 part19]$ cat data3.txt 
Line1
Line2
Line3

[ttxie@41 part19]$ gawk 'BEGIN {print "file contents:"}; {print $0}' data3.txt 
file contents:
Line1
Line2
Line3

19.1.2.7 在處理數(shù)據(jù)后運(yùn)行腳本

使用 END 關(guān)鍵字可以強(qiáng)制 gawk 在讀取數(shù)據(jù)結(jié)束之后執(zhí)行指定腳本,效果如下:

[ttxie@41 part19]$ gawk 'BEGIN {print "file contents:"}; {print $0}; END {print "End of file"}' data3.txt 
file contents:
Line1
Line2
Line3
End of file

19.1.2.8 通過 FS 變量指定字段分隔符

如果是在文件中編寫腳本,可以使用特殊變量 FS 來指定字段分隔符,效果如下:

image.png

在上圖中,BEGIN 關(guān)鍵字部分的輸出內(nèi)容沒有顯示出來,知道是為什么嗎?
因?yàn)樽詈髮⑤敵鐾ㄟ^管道傳入了 tail -n 5 命令,該命令的效果是輸出最后 5 行數(shù)據(jù),所以最開始輸出的內(nèi)容也沒無法顯示了,這并不是腳本 BUG 。

19.2 sed 編輯器基礎(chǔ)

介紹一些常用的 sed 命令。

19.2.1 更多的替換選項(xiàng)

通過一些選項(xiàng),讓 s 命令 在替換文本時操作更靈活。

19.2.1.1 替換標(biāo)記

默認(rèn)情況下,在執(zhí)行替換命令時,只會替換每行出現(xiàn)的第一個匹配項(xiàng),如果每行有超過一個匹配項(xiàng),那么后續(xù)的都會被忽略,效果如下:

[ttxie@41 part19]$ cat data.txt 
This is a test of the test script
This is the second test of the test script

[ttxie@41 part19]$ sed 's/test/trail/' data.txt
This is a trail of the test script
This is the second trail of the test script

在上圖中可以看到,目標(biāo)文本中每行都有兩個 test ,sed 命令希望將 test 替換成 trail ,但命令執(zhí)行后,每行都只有第一個 test 被替換了,后續(xù)的 test 沒有發(fā)生變化。

如果添加 替換標(biāo)記 ,有一種方式可以解決上述情況。首先了解一下替換標(biāo)記的四種可用方式:

image

在上述方式中,第二種標(biāo)記又被叫做全局替換,效果如下:

[ttxie@41 part19]$ sed 's/test/trail/g' data.txt
This is a trail of the trail script
This is the second trail of the trail script

從上圖中可以看到,指定文件中,所有的 test 都被替換成了 trail 。

第一種方式是通過數(shù)字標(biāo)記,指定要替換的匹配項(xiàng),效果如下:
只替換每行中第二次出現(xiàn)的匹配模式。

[ttxie@41 part19]$ sed 's/test/trail/2' data.txt
This is a test of the trail script
This is the second test of the trail script

第三種方式是將被替換行的內(nèi)容打印出來,效果如下:

[ttxie@41 part19]$ cat data.txt 
This is a test of the test script
This is the second test of the test script
[ttxie@41 part19]$ 
[ttxie@41 part19]$ sed 's/second/third/' data.txt 
This is a test of the test script
This is the third test of the test script
[ttxie@41 part19]$ sed 's/second/third/p' data.txt 
This is a test of the test script
This is the third test of the test script
This is the third test of the test script
[ttxie@41 part19]$ sed -n 's/second/third/p' data.txt 
This is the third test of the test script

在上圖中可以看到,使用 sed 命令后的替換目標(biāo)是 second 字段,該字段只有第二行數(shù)據(jù)存在一次匹配。當(dāng)?shù)谝淮问褂迷撁詈?,將所有被掃描的行都進(jìn)行輸出。當(dāng)?shù)诙卧谔鎿Q命令某位替換 p 標(biāo)記 后,在所有被掃描的行都輸出后,再次輸出了被替換內(nèi)容的第二行,這就是 p 標(biāo)記 的效果。
所以在使用該命令時一般會攜帶 sed -n 命令,-n 選項(xiàng)可以屏蔽 sed 命令默認(rèn)的輸出內(nèi)容,結(jié)合 p 標(biāo)記 的效果,就可以只顯示被替換內(nèi)容的行,如上圖第三次的效果。

第四種方式是將被替換內(nèi)容的行輸出到指定文件,效果如下:

[ttxie@41 part19]$ cat data.txt 
This is a test of the test script
This is the second test of the test script
[ttxie@41 part19]$ sed 's/second/third/w result.txt' data.txt 
This is a test of the test script
This is the third test of the test script
[ttxie@41 part19]$ cat result.txt 
This is the third test of the test script

在上圖中可以看到,命令執(zhí)行完成后,查看 result.txt 的內(nèi)容就是被替換內(nèi)容的第二行。

19.2.1.2 替換字符

sed 命令中替換內(nèi)容時,如果部分內(nèi)容涉及到敏感字符,例如本身就要作為替換操作分隔符的 正斜線( / ) ,那么操作起來就非常麻煩,效果如下:

[ttxie@41 part19]$ sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd |head

root:x:0:0:root:/root:/bin/csh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

這個時候其實(shí)可以指定其他字符來作為替換操作的分隔符,例如 感嘆號( ! ) ,效果如下:

[ttxie@41 part19]$ sed 's!/bin/bash!/bin/csh!' /etc/passwd |head

root:x:0:0:root:/root:/bin/csh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

19.2.2 使用地址

默認(rèn)情況下,sed 命令會作用到指定數(shù)據(jù)的所有行。如果想讓命令作用于特定行或某些行,就需要用到 行尋址( Line Addressing ) 。
在 sed 編輯器中有兩種行尋址方式:

  • 通過數(shù)字形式指定行區(qū)間
  • 通過文本模式過濾指定行

19.2.2.1 數(shù)字形式的行尋址

sed 編輯器會將目標(biāo)文本的第一個編號為 1 ,第二行編號為 2 ,以此類推。在使用數(shù)字形式的行尋址時,有以下三種方式可選:
1. 2s ,表示單個只影響第二行
2. 2,3s ,表示影響第二到第三行
3. 2,$s ,表示從第二行開始,一直到最后一行都受影響,美元符號( $ ) 表示最后一行

第一種形式的效果如下:

[ttxie@41 part19]$ cat data1.txt 

The quick brown for jumps overs the lazy dog
The quick brown for jumps overs the lazy dog
The quick brown for jumps overs the lazy dog
The quick brown for jumps overs the lazy dog

[ttxie@41 part19]$ sed '2s/dog/cat/' data1.txt 

The quick brown for jumps overs the lazy dog
The quick brown for jumps overs the lazy cat
The quick brown for jumps overs the lazy dog
The quick brown for jumps overs the lazy dog

在上圖中可以看到,只有第二行數(shù)據(jù)發(fā)生了變化。

第二種形式的效果如下:

[ttxie@41 part19]$ sed '2,3s/dog/cat/' data1.txt 
The quick brown for jumps overs the lazy dog
The quick brown for jumps overs the lazy cat
The quick brown for jumps overs the lazy cat
The quick brown for jumps overs the lazy dog

在上圖中可以看到,第二行和第三行的數(shù)據(jù)都發(fā)生了變化。

第三種形式的效果如下:

[ttxie@41 part19]$ sed '2,$s/dog/cat/' data1.txt 
The quick brown for jumps overs the lazy dog
The quick brown for jumps overs the lazy cat
The quick brown for jumps overs the lazy cat
The quick brown for jumps overs the lazy cat

在上圖中可以看到,從第二行開始一直到最后一行的數(shù)據(jù)都發(fā)生了變化。

19.2.2.2 使用文本模式過濾器

sed 編輯器允許對存在指定文本的行進(jìn)行內(nèi)容替換,效果如下:

image

在上圖中可以看到,sed 命令首先在目標(biāo)文本中找到 asing1elife 存在的行,然后將該行的 My 替換成 He ,而其他不存在 asing1elife 的行則不受影響。
該模式如果結(jié)合正則表達(dá)式,將會發(fā)揮更強(qiáng)大的威力。

19.2.2.3 命令組合

如果希望在單行執(zhí)行多個命令,使用 花括號多行模式 下將多個命令進(jìn)行包裹即可,效果如下:

[ttxie@41 part19]$ cat data1.txt 
The quick brown fox jumps overs the lazy dog
The quick brown fox jumps overs the lazy dog
The quick brown fox jumps overs the lazy dog
The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed '2{
s/fox/elephant/
s/dog/cat/
}' data1.txt
The quick brown fox jumps overs the lazy dog
The quick brown elephant jumps overs the lazy cat
The quick brown fox jumps overs the lazy dog
The quick brown fox jumps overs the lazy dog

在上圖中可以看到,sed 命令首先指定了受影響的行數(shù)是第二行,然后在第二行中進(jìn)行了兩次替換。

19.2.3 刪除行

使用 d 命令 可以刪除 尋址模式匹配到的指定行,d 命令 的尋址模式和 s 命令 的規(guī)則一致。
該命令需要注意以下兩點(diǎn):
1. 只影響流輸出,不會影響原文件
2. 必須加入尋址模式,否則流輸出的所有數(shù)據(jù)都會被刪除

指定單行的效果如下:

[ttxie@41 part19]$ cat data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed '2d' data1.txt 
1.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog

指定多行的效果如下:
指定開始行到最后一行的效果如下:

[ttxie@41 part19]$ sed '2,3d' data1.txt 
1.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed '2,$d' data1.txt 
1.The quick brown fox jumps overs the lazy dog

指定文本的效果如下:

[ttxie@41 part19]$ sed '/2./d' data1.txt 
1.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog

還可以通過文本的方式來指定范圍,效果如下:

[ttxie@41 part19]$ sed '/2./,/3./d' data1.txt 
1.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog

但該模式要慎用,因?yàn)閷τ?sed 編輯器來說,第一個文本的匹配是打開了行刪除功能,第二個文本的匹配則是關(guān)閉了行刪除功能。所以如果一直沒有匹配到第二個文本,就會因?yàn)闊o法關(guān)閉行刪除功能而導(dǎo)致將后續(xù)的內(nèi)容全部刪除,效果如下:

[ttxie@41 part19]$ sed '/2./,/5./d' data1.txt 
1.The quick brown fox jumps overs the lazy dog

又或者目標(biāo)文件的數(shù)據(jù)存在重復(fù),就會導(dǎo)致 sed 編輯器再次匹配到第一個文本而打開行刪除功能,效果如下:

[ttxie@41 part19]$ cat data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
[ttxie@41 part19]$ 
[ttxie@41 part19]$ sed '/2./,/3./d' data1.txt 
1.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog

19.2.4 插入和附加文本

sed 編輯器的 i 命令 會在指定行之前增加一行新數(shù)據(jù),a 命令 會在指定行之后增加一行新數(shù)據(jù),效果如下:

[ttxie@41 part19]$ cat data1.txt
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed '2{
i\插入新數(shù)據(jù)
a\追加新數(shù)據(jù)
}' data1.txt

1.The quick brown fox jumps overs the lazy dog
插入新數(shù)據(jù)
2.The quick brown fox jumps overs the lazy dog
追加新數(shù)據(jù)
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog

需要注意的是,插入和附加命令使用的是反斜線( \ ) ,而替換命令使用的是正斜線( / )。

如果要同時插入或追加多行文本,需要在使用多行模式時,在每行文本的末尾添加 反斜線( \ ) ,效果如下:
$代表最后一行。

[ttxie@41 part19]$ sed '${
i\插入新數(shù)據(jù)
a\追加新數(shù)據(jù)
}' data1.txt

1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog
插入新數(shù)據(jù)
2.The quick brown fox jumps overs the lazy dog
追加新數(shù)據(jù)

19.2.5 修改行(change)

sed 編輯器的 c 命令 會修改指定行的所有數(shù)據(jù)內(nèi)容,效果如下:

[ttxie@41 part19]$ sed '2c\這一行被修改了' data1.txt
1.The quick brown fox jumps overs the lazy dog
這一行被修改了
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog

需要注意的是,修改命令使用的也是反斜線( \ ) 。

19.2.6 轉(zhuǎn)換命令

sed 編輯器的 y 命令 可以處理單個字符,格式是 sed [address]y/inchars/outchars/ ,該命令會將 inchars 中的每個字符與 outchars 中的每個字符進(jìn)行一一對應(yīng)后分別替換,效果如下:

[ttxie@41 part19]$ cat data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed 'y/123/789/' data1.txt 

7.The quick brown fox jumps overs the lazy dog
8.The quick brown fox jumps overs the lazy dog
9.The quick brown fox jumps overs the lazy dog
4.The quick brown fox jumps overs the lazy dog
8.The quick brown fox jumps overs the lazy dog

在上圖中可以看到,轉(zhuǎn)換命令默認(rèn)就是全局效果 ,并不像替換命令一樣需要使用 g 選項(xiàng)來打開全局替換效果。不過遺憾的是,轉(zhuǎn)換命令的轉(zhuǎn)換效果是否全局,是不可選的,缺省就是全局,也只能是全局轉(zhuǎn)換。

需要注意的是,inchars 和 outchars 的長度必須相同,否則會報錯,效果如下:

[ttxie@41 part19]$ sed 'y/123/7890/' data1.txt 
sed: -e expression #1, char 11: strings for `y' command are different lengths

19.2.7 回顧打印

除了替換命令中的 p 選項(xiàng) 可以用于打印被替換的行,還有以下三個命令可以打印數(shù)據(jù)流的信息:
1. p 命令 用于打印文本行
2. = 命令 用于打印行號
3. l 命令 用于列出行,是小寫的 L

19.2.7.1 打印行

p 命令 可以打印指定的行內(nèi)容,但建議和 sed -n 命令結(jié)合使用,效果如下:

[ttxie@41 part19]$ cat data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed '/3./p' data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed -n '/3./p' data1.txt 
3.The quick brown fox jumps overs the lazy dog

在上圖中可以看到,第一次使用 p 命令時,由于 sed 編輯器默認(rèn)的輸出效果,首先輸出了完整的流數(shù)據(jù),才輸出了 p 命令匹配的行內(nèi)容。第二次結(jié)合 sed -n 命令屏蔽了默認(rèn)輸出后,就可以只看到 p 命令的輸出結(jié)果了。

p 命令也支持行尋址,效果如下:

[ttxie@41 part19]$ cat data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed '2,3p' data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed -n '2,3p' data1.txt 
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

19.2.7.2 打印行號

sed 編輯器默認(rèn)會為目標(biāo)文本的每一行添加編號,使用 = 命令 可以將這個編號輸出,效果如下:

[ttxie@41 part19]$ sed '=' data1.txt 
1
1.The quick brown fox jumps overs the lazy dog
2
2.The quick brown fox jumps overs the lazy dog
3
3.The quick brown fox jumps overs the lazy dog

19.2.7.3 列出行

l 命令 的作用是打印出數(shù)據(jù)流中原本不可打印的 ASCII 字符,效果如下:

image

19.2.8 使用 sed 處理文件

19.2.8.1 寫入文件

w 命令 可以將目標(biāo)文件的指定行寫入到指定文件,效果如下:

[ttxie@41 part19]$ cat data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ sed -n  '2,3w result.txt' data1.txt 

[ttxie@41 part19]$ cat result.txt 
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

19.2.8.2 從文件讀取數(shù)據(jù)

r 命令 允許將指定文件的內(nèi)容插入到目標(biāo)文件的指定位置,效果如下:

[ttxie@41 part19]$ cat data1.txt 
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
3.The quick brown fox jumps overs the lazy dog

[ttxie@41 part19]$ cat dataIn.txt 
準(zhǔn)備插入的第一行數(shù)據(jù)
準(zhǔn)備插入的第二行數(shù)據(jù)

[ttxie@41 part19]$ sed '2r dataIn.txt' data1.txt
1.The quick brown fox jumps overs the lazy dog
2.The quick brown fox jumps overs the lazy dog
準(zhǔn)備插入的第一行數(shù)據(jù)
準(zhǔn)備插入的第二行數(shù)據(jù)
3.The quick brown fox jumps overs the lazy dog

讀取命令和刪除命令配合使用

首先匹配2.字符串,在占用文本后插入名單后,直接將匹配行進(jìn)行刪除。

[ttxie@41 part19]$ sed '/2./{                       
r dataIn.txt
d
'} data1.txt
1.The quick brown fox jumps overs the lazy dog
準(zhǔn)備插入的第一行數(shù)據(jù)
準(zhǔn)備插入的第二行數(shù)據(jù)
3.The quick brown fox jumps overs the lazy dog

轉(zhuǎn)載來自:
作者:asing1elife
鏈接:http://www.itdecent.cn/p/f13e7e847731
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容