『忘了再學』Shell基礎 — 30、sed命令的使用

2022-06-13 12:02:19

1、sed命令說明

sed主要是用來將資料進行選取、替換、刪除、新增的命令,grepawksed稱為是文字操作三劍客。

我們看看sed命令的語法格式:

[root@localhost ~]# sed [選項] '[動作]' 檔名

選項:

  • -n:一般sed命令會把所有資料都輸出到螢幕,如果加入此選擇,則只會把經過sed命令處理的行輸出到螢幕。
  • -e:允許對輸入資料應用多條sed命令編輯。
  • -f 指令碼檔名:從sed指令碼中讀入sed操作。和awk命令的-f非常類似。
  • -r:在sed中支援擴充套件正規表示式。
  • -i:用sed的修改結果直接修改讀取資料的檔案,而不是由螢幕輸出。

動作:

  • a \:追加,在當前行後新增一行或多行。新增多行時,除最後一行外,每行末尾需要用\代表資料未完結。(如果不新增多行,就忽略\
  • c \:行替換,用c後面的字串替換原資料行,替換多行時,除最後一行外,每行末尾需用\代表資料未完結。(如果不新增多行,就忽略\
  • i \:插入,在當期行前插入一行或多行。插入多行時,除最後一行外,每行末尾需要用\代表資料未完結。(如果不新增多行,就忽略\
  • d:刪除,刪除指定的行。
  • p:列印,輸出指定的行。
  • s:字串替換,用一個字串替換另外一個字串。格式為行範圍 s/舊字串/新字串/g(和vim中的替換格式類似)。

提示:

對於sed命令大家要注意,sed所做的修改並不會直接改變檔案的內容(如果是用管道符接收的命令的輸出,這種情況連檔案都沒有),而是把修改結果只顯示到螢幕上,除非使用-i選項才會直接修改檔案。

小說明:

vim可以直接修改檔案內容,我們使用的也非常多,為什麼還要學sed命令呢?

因為vim需要我們手動和計算機互動,需要手動輸入一些編輯指令,儲存指令,切換模式指令等,才能完成vim的編輯操作。

在Shell中很難做到人機互動,所以vim操作沒有辦法在Shell程式使用,因此要通過sed命令來完成,這是Shell中修改檔案內容最最最主要的方式。

2、行資料操作

使用如下文字student.txt

ID      Name    Python  Linux   MySQL   Java
1       Tangs   88      87      86      85.55
2       Sunwk   99      98      97      96,66
3       Zhubj   77      76      75      74.44
4       Shahs   66      65      64      63.33

(1)檢視檔案中的資料

我們舉幾個例子來看看sed命令到底是幹嘛的。

檢視下student.txt檔案的第二行,那麼就可以利用p動作,執行如下命令:

[root@localhost tmp]# sed '2p' student.txt
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
3   Zhubj   77      76      75      74.44
4   Shahs   66      65      64      63.33

從上面的結果可以看出,p命令確實輸出了第二行資料,但是sed命令還會把所有資料都輸出一次,這時就會看到這個比較奇怪的結果,第二行的資料有兩次的輸出。

那如果想指定輸出某行資料,就需要-n選項的幫助。

[root@localhost tmp]# sed -n '2p' student.txt
1   Tangs   88  87  86  85.55

(2)刪除檔案中的資料

刪除student.txt文字中第二行到第四行的資料,命令如下:

[root@localhost tmp]# sed  '2,4d' student.txt
ID  Name    Python  Linux   MySQL   Java
4   Shahs   66      65      64      63.33

2,4表示刪除2至4行的資料。

但是這裡要注意的是,我上邊的操作,並沒有寫入到檔案中,我們可以檢視student.txt文字中的內容:

[root@localhost tmp]# cat student.txt 
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
3   Zhubj   77      76      75      74.44
4   Shahs   66      65      64      63.33

可以看到student.txt文字中的內容還在,sed命令只是在輸出的時候,把資料過濾掉了。

如果需要在刪除內容的同時,再寫入檔案,就需要-i選項了。

執行命令:

[root@localhost tmp]# sed -i '2,4d' student.txt就可以了。

(3)向檔案中追加資料

需求:在student.txt文字中第三行後面新增66666666666666。

執行命令如下:

[root@localhost tmp]# sed "3a 66666666666666" student.txt 
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
66666666666666
3   Zhubj   77      76      75      74.44
4   Shahs   66      65      64      63.33

同理,student.txt文字中的內容並沒有被改變,如果需要改變student.txt文字中的內容,新增-i選項。

注意:sed命令的選項要寫在單引號(雙引號也可以)之外,如:

[root@localhost tmp]# sed -i "3a 66666666666666" student.txt

(4)向檔案中插入資料

需求:在student.txt文字中第三行前面新增88888888888。

執行命令如下:

[root@localhost tmp]# sed "3i 88888888888888" student.txt
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
88888888888888
2   Sunwk   99      98      97      96.66
66666666666666
3   Zhubj   77      76      75      74.44
4   Shahs   66      65      64      63.33

同理,需要把修改寫入檔案,需要新增-i選項。

(5)修改檔案中的多行資料(刪除,追加,插入)

如果是想追加或插入多行資料,除最後一行外,每行的末尾都要加入\代表資料未完結。

需求:向student.txt文字中第二行後面追加hello world

執行如下命令:

[root@localhost tmp]# sed '2a hello \
> world' student.txt
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
hello
world
2   Sunwk   99      98      97      96.66
3   Zhubj   77      76      75      74.44
4   Shahs   66      65      64      63.33

(引號不完全是不會執行的)

提示:我發現換行後tab鍵提示功能不能用了。(不清楚怎麼回事)

這裡在說明一下-n選項,-n選項只會把經過sed命令處理的行輸出到螢幕。

執行如下命令:

[root@localhost tmp]# sed -n '2a hello \
world' student.txt
hello
world

(6)替換檔案中的整行文字

需求:替換student.txt文字中的第二行資料為999999999999999。

執行如下命令:

[root@localhost tmp]# sed '2c 999999999999999' student.txt
ID  Name    Python  Linux   MySQL   Java
999999999999999
2   Sunwk   99      98      97      96.66
3   Zhubj   77      76      75      74.44
4   Shahs   66      65      64      63.33

注意:sed命令預設情況是不會修改檔案內容的,如果確定需要讓sed命令直接處理檔案的內容,可以使用-i選項。不過要小心啊,這樣非常容易誤操作,在作業系統檔案時請小心謹慎。

(7)字串替換

sedc動作是進行整行替換的,如果僅僅想替換行中的部分資料,就要使用s動作了。

需求:修改Zhubj的Java成績為100。

執行如下命令:

# 命令格式
[root@localhost tmp]# sed 's/舊字串/新字串/g' 檔名

# 執行命令
[root@localhost tmp]# sed 's/74.44/100/g' student.txt
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
3   Zhubj   77      76      75      100
4   Shahs   66      65      64      63.33

# 或者對行範圍更精準一些
[root@localhost tmp]# sed '4s/74.44/100/g' student.txt
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
3   Zhubj   77      76      75      100
4   Shahs   66      65      64      63.33

注意:

4s/74.44/100/g表示式中s/之間不能有空格。

如果4s/74.44/100/g不寫行號,也就是上面第一種寫法,就代表替換整個檔案中的匹配字串。

(8)同時執行多條動作

sed命令中,-e選項可以同時執行多個sed動作,當然如果只是執行一個動作也可以使用-e選項,但是這時-e選項是沒有什麼意義的。

還要注意多個動作之間要用;號或回車分割。

練習1:

需求:把Shahs的成績註釋掉,並且把Zhubj的Python成績改成100。

執行命令如下:

# 使用;分號的方式隔離多條動作
[root@localhost tmp]# sed -e '5s/^/#/g ; 4s/77/100/g' student.txt
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
3   Zhubj   100     76      75      74.44
#4  Shahs   66      65      64      63.33

注意:

^代表行首,是正規表示式,不用加-r選項也可以。

其實上面命令中不寫-e選項,命令也是可以執行的,應該是預設識別的。

但是我們儘量規範書寫。

# 使用回車的方式隔離多條動作
[root@localhost tmp]# sed -e '5s/^/#/g
> 4s/77/100/g' student.txt
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
3   Zhubj   100     76      75      74.44
#4  Shahs   66      65      64      63.33

注意:使用回車的方式進行動作之間的分隔,就不能在寫分號;了。

特別注意:

sed命令中有多條動作執行的時候,且有多個選項的時候,-e選項要緊挨動作表示式,否則會報錯。

例如:

-i -e '5s/^/#/g'正確,

-e -i '5s/^/#/g'報錯。

練習2:

刪除字串使用sed命令的d操作是不能實現的,因為d操作是刪除整行。這時就需要字串替換,也就是sed命令的s動作來完成。

需求:刪除Zhubj的Python成績。

執行如下命令:

# 用空代替
[root@localhost tmp]# sed '4s/77//g' student.txt 
ID  Name    Python  Linux   MySQL   Java
1   Tangs   88      87      86      85.55
2   Sunwk   99      98      97      96.66
3   Zhubj           76      75      74.44
4   Shahs   66      65      64      63.33

3、總結

什麼時候需要使用sed命令?

如果需要在指令碼程式中,修改檔案中的資料,這種情況下我們就需要使用sed命令。