『忘了再學』Shell基礎 — 30、sed命令的使用
- 2022 年 6 月 13 日
- 筆記
- 高級測試技能 - Shell基礎
1、sed命令說明
sed
主要是用來將數據進行選取、替換、刪除、新增的命令,grep
,awk
,sed
稱為是文本操作三劍客。
我們看看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)字符串替換
在sed
中c
動作是進行整行替換的,如果僅僅想替換行中的部分數據,就要使用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
命令。