linux sed命令


一、初識sed

在部署openstack的過程中,會接觸到大量的sed命令,比如

# Bind MySQL service to all network interfaces.
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf

那么這條命令是什么意思?接下來介紹sed命令答案自然就揭曉了。

二、sed簡介

sed:是一個編輯器,是一個強大的文件處理工具。

sed作用:用來替換、刪除,更新文件中的內容。sed能自動處理一個或多個文件。

sed原理:sed以文本的行為單位進行處理,一次處理一行內容。首先sed把當前處理的行存儲在臨時緩沖區中(稱為模式空間pattern space),接着處理緩沖區中的行,處理完成后,把緩沖區的內容送往屏幕。sed處理完一行就將其從臨時緩沖區刪除,然后將下一行讀入,進行處理和顯示,這樣不斷的重復,直到文件末尾。處理完文件的最后一行后,sed便結束運行。

因為sed是對文件中每行在臨時緩沖區中的副本進行編輯,所以原文件內容並沒有改變,除非重定向輸出。

三、sed命令介紹

#sed [-nefri][命令]

參數說明:

-i:直接修改文件,終端不輸出結果

-n:使用安靜(slient)模式,取消默認輸出。sed默認會將所有來自stdin的數據輸出到終端上。但如果加上-n參數后,不自動打印處理后的結果,只是默默的處理,只有經過sed特殊處理的那一行才被列出來。

-e: --expression直接在命令模式上進行sed的動作編輯。sed -e '...' -e '...' -e '...'

-f:指定sed腳本的文件名。

-r:sed動作支持的是延伸型正規表示法的語法。(默認是基礎正規表示法語法)

命令說明:[n1][n2]命令

n1,n2:表示行號,該參數可選,一般表示希望操作的行數,可以是數字,正則表達式或二者混合。

用逗號分隔的兩個行數表示這兩行為起止的行的范圍。如1,3表示1,2,3行,美元符號($)表示最后一行。如何沒有指定地址,sed將處理輸入文件的所有行。地址通常的寫法有:n;n,m;n,$。舉例,如果我的操作是需要在3到5行之間進行的,則【3,5,[動作行為]】。

命令:

a:新增,在當前行的下一行追加一行文本。

i:插入,在當前行的上一行插入一行文本。

c:替換,以行為單位進行替換,c的后面可以跟字符串,用這些字符串取代n1,n2之間的行。

d:刪除,從模式空間刪除一行。

p:打印,打印模式空間的行。通常p會與參數【-n】一起使用。

s:替換,通常s命令可以搭配正則表達式例如1,20s/old/new/g。

四、舉例

下面我們拿Emilia的Big Big World中的部分歌詞文件song.txt舉例,其內容如下:

$ cat song.txt
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

1、s替換命令

將song.txt文件中每行的第一個big替換為small:

sed 's/big/small/' song.txt

解釋:s:替換命令,/big/:匹配big字符串,/small/:把匹配替換成small。

$ sed 's/big/small/' song.txt
I'm a small big girl
In a small big world
It's not a small big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

將song.txt文件中每行所有的big替換為small:

sed 's/big/small/g' song.txt

解釋:同上,/g表示一行上替換所有的匹配

$ sed 's/big/small/g' song.txt
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

Note:這里也可以使用 sed 's#big#small#g' song.txt  ,緊跟s命令的符號都會被認為是查找串和替換串之間的分隔符,這里使用#,其實無論什么字符串(換行符,反斜線除外),只要緊跟s命令,就成了新的串分隔符。

將song.txt文件中每行第2個big替換為small: sed 's/big/small/2' song.txt

解釋:/2表示指定一行中第2個匹配的字段操作

$ sed 's/big/small/2' song.txt 
I'm a big small girl
In a big small world
It's not a big small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

2、-i參數直接修改文件內容

上面的sed命令沒有改變song.txt,只是把處理后的內容輸出,如果要寫回文件,可以使用重定向。

$ sed 's\big\small\g' song.txt >song.bak

或使用-i直接修改文件內容:sed -i 's\big\small\g' song.txt

$ sed -i 's\big\small\g' song.txt 
$ cat song.txt
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

sed 的[-i]參數可以直接修改文件內容,該功能非常有用!

舉例來說,如果有一個100萬行的文件,要在第100行加某些文字。此時使用vim可能會瘋掉!因為文件太大了打不開!但是通過sed直接修改/取代的功能,根本不需要打開文件就能完成任務。和vim相比sed就像會魔術一樣,vim要打開文件-操作文件-關閉文件,sed直接隔空就對文件操作了,非常方便。

正因為sed -i 功能強大,可以直接修改原始文件,也是個危險的動作,需小心使用。

3、-e參數編輯命令,進行多行匹配

-e是編輯命令,用於sed執行多個編輯任務的情況下。在下一行開始編輯前,所有的編輯動作都將應用到模式緩沖區中的行上。因為是逐行進行多重編輯(即每個命令都在模式空間的當前行上執行),所以編輯命令的順序會影響結果

如果我們要一次替換多個模式,

sed "1,3s/big/small/g; 4,5s/do/don't/g" song.txt

解釋:第一個模式:把第一行到第三行的big替換成small;第二個模式:把第四行到第五行的do替換成don't。

$ sed "1,3s/big/small/g; 4,5s/do/don't/g" song.txt
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I don't don't feel
that I don't don't will miss you much
Miss you much

上面的命令等價於:sed  -e "1,3s/big/small/g" -e "4,5s/do/don't/g" song.txt 

$ sed  -e "1,3s/big/small/g" -e "4,5s/do/don't/g" song.txt  
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I don't don't feel
that I don't don't will miss you much
Miss you much

4、刪除命令d:刪除匹配的行

命令d刪除匹配的輸入行,sed先將輸入行從文件復制到模式空間里,然后對該行執行sed命令,最后將模式空間的內容顯示在屏幕上。如果是命令d,當前模式空間里的輸入行會被刪除,不被顯示。

利用匹配刪除行

刪除song.txt文件中第一次包含“Miss”的行 :sed '/Miss/d' song.txt

$ sed '/Miss/d' song.txt 
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much

下面是利用行號刪除行的例子

刪除song.txt文件中的第1行:sed '1d' song.txt

$ sed '1d' song.txt 
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

刪除song.txt文件中2到5行:sed '2,5d' song.txt  

$ sed '2,5d' song.txt   
I'm a big big girl
Miss you much

刪除song.txt文件中第3行之后的行:sed '3,$d' song.txt

$ sed '3,$d' song.txt 
I'm a big big girl
In a big big world

正則匹配可以和行號一起使用,舉一個openstack部署中的例子:

刪除第一次包含“eth2”的行到最后所有的行:sed -i '/eth2/,$d' /etc/network/interfaces

5、插入命令a,在當前行后追加一行

a添加新文本到文件中當前行(即讀入模式空間中的行)的后面。

在song.txt文件中第3行后插入一行並直接作用於song.txt:sed '3a AAAAAAAAAAAAAAAAAAAAAAA' song.txt 【用空格作為分隔符】

$ sed -i '3a AAAAAAAAAAAAAAAAAAAAAAA' song.txt 
$ cat song.txt
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
AAAAAAAAAAAAAAAAAAAAAAA
But I do do feel
that I do do will miss you much
Miss you much

在匹配'Miss'的行后插入一行:sed '/Miss/a AAAAAAAAAAAAAAAAAAAAAAAAAA' song.txt 【用空格作為分隔符】

$ sed '/Miss/a AAAAAAAAAAAAAAAAAAAAAAAAAA' song.txt                                
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
AAAAAAAAAAAAAAAAAAAAAAAAAA

在song.txt最后插入一行:sed '$a append line' song.txt

$ sed '$a append line' song.txt 
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
append line

6、插入命令i,在當前行前插入一行

i添加新文本到文件中當前行(即讀入模式空間中的行)的前面。

在song.txt文件中第3行后插入一行:sed '3i#iiiiiiiiiiiiiiiiiiiiiiiiiii' song.txt  【#作為分隔符】

$ sed '3i#iiiiiiiiiiiiiiiiiiiiiiiiiii' song.txt                
I'm a small small girl
In a small small world
iiiiiiiiiiiiiiiiiiiiiiiiiii
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

在song.txt文件中匹配'Miss'的行前面插入一行:sed '/Miss/i iiiiiiiiiiiiiii' song.txt【空格作為分隔符】

$ sed '/Miss/i iiiiiiiiiiiiiii' song.txt                           
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
iiiiiiiiiiiiiii
Miss you much

7、新增多行(i行前插入,a行后追加,其他地方一樣,以a為例)

插入相同的行,在第2行到第5行之后均插入一行:sed '2,5a append one line ' song.txt

$ sed '2,5a append one line ' song.txt 
I'm a big big girl
In a big big world
append one line 
It's not a big big thing if you leave me
append one line 
But I do do feel
append one line 
that I do do will miss you much
append one line 
Miss you much

插入不同的行,以\n換行

在第2行后面插入三行:sed '2a append one line \nappend two line \nappend three line' song.txt

liuxiaoyan@development:~/mytest$ sed '2a append one line \nappend two line \nappend three line' song.txt   
I'm a big big girl
In a big big world
append one line append two line append three line
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much

8、c命令以行為單位替換

 把第2到第5行的內容替換為2-5content:sed '2,5c 2-5content' song.txt

$ sed '2,5c 2-5content' song.txt 
I'm a big big girl
2-5content
Miss you much

9、p命令顯示模式空間的內容

以行為單位顯示,

顯示song.txt文件中的第2到第5行: sed -n '2,5p' song.txt

$ sed -n '2,5p' song.txt 
In a big big world It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much

搜索匹配顯示:

顯示匹配'Miss'的行:sed -n '/Miss/p' song.txt

$ sed -n '/Miss/p' song.txt 
Miss you much

10、-n參數取消默認輸出

上面的p命令顯示時,用到-n參數,因為sed默認把輸入行打印在屏幕上:sed '/Miss/p' song.txt

liuxiaoyan@development:~/mytest$ sed '/Miss/p' song.txt    
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much Miss you much
Miss you much

所以要打印選定內容,用-n配合p來使用。

五、簡單正則表達式

^:行首定位符。

$:行尾定位符。

\<:詞首定位符。

\>:詞尾定位符。

.:匹配除換行以外的單個字符。

*:匹配0個或多個前導字符。

[]:匹配字符集合里的任一字符。

[^] :匹配不在指定字符集合里的任一字符。

 

更深入了解可參考以下資料:

《shell基礎十二篇》

sed 簡明教程- 酷殼陳皓


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM