概述
sed是一個流編輯器(Stream EDitor)。主要用于自動編輯一個或多個文件;簡化對文件的反復操作;編寫轉換程序等。本文主要講述了:
-
sed工作原理
-
sed命令格式及常用選項
-
應用實例
-
高級編輯命令
sed工作原理
sed命令運行過程中維護著兩個緩沖區,一個是活動的“模式空間(pattern
space)”,另一個是起輔助作用的“暫存緩沖區(holding space)”。sed每次處理一行內容,整個文件像流水一樣被逐行處理然后逐行輸出。處理時,把當前處理的行存儲在”模式空間”(pattern space ),接著用sed 命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。接著處理下一行,這樣不斷重復,直到文件末尾。工作過程如下圖所示:
一般情況下暫存緩沖區是用不到的,但有特殊的命令可以在模式空間與暫存緩沖區之間交換數據,由于sed對文本的所有操作都是在模式空間里進行的,所以,默認情況下,sed不會對原文件內容修改,處理后的所有輸出行都被打印到屏幕上,除非你使用重定向存儲輸出。
sed命令格式及常用選項
用法:
sed [OPTION]... PATTERN [input-file]...
OPTION:
-n:不輸出模式空間中的內容至屏幕; -e script, --expression=script:多點編輯; -f /PATH/TO/SED_SCRIPT_FILE 每行一個編輯命令; -r,--regexp-extended:支持使用擴展正則表達式; -i[SUFFIX], --in-place[=SUFFIX]:直接編輯原文件 ; #一般不建議-i,如需進行文件修改,強烈建議先備份,即-i.CHAR。(.CHAR為備份文件后綴名,可自定義。)
PATTERN:
PATTERN是一組特定的sed命令(很多時候也稱之SCRIPT),一定要被包含在一對單引號中,以免被shell解釋,其格式如下:
'[address-range]sed-command'
address-range是指要處理的行的范圍,又叫地址界定;
sed-command是一個sed命令,用來對指定的行進行處理。
地址界定:
1. 空地址:對全文進行處理; 2. 單地址: n:指定第n行; /pattern/:被此模式所匹配到的每一行; 3. 地址范圍 n,m:第n行開始至第m行 n,+m:第n行開始,至后面的m行 n,/pat1/:第n行開始,至第一次匹配pat1的行 /pat1/,/pat2/:第一個匹配pat1的行開始,至第一個匹配pat2的行 $:最后一行; 4. ~步進: n~m:第n行開始,每次步進m行 1~2:所有奇數行 2~2:所有偶數行
編輯命令:
d:刪除; p:顯示模式空間中的內容; a \text:在行后面追加文本“text”,支持使用\n實現多行追加; i \text:在行前面插入文本“text”,支持使用\n實現多行插入; c \text:把匹配到的行替換為此處指定的文本“text”; w /PATH/TO/SOMEFILE:保存模式空間匹配到的行至指定的文件中; r /PATH/FROM/SOMEFILE:讀取指定文件的內容至當前文件被模式匹配到的行后面;文件合并; =:為模式匹配到的行打印行號; !:條件取反; 地址定界!編輯命令; s///:查找替換,其分隔符可自行指定,常用的有s@@@, s###等; 替換標記: g:全局替換; w /PATH/TO/SOMEFILE:將替換成功的結果保存至指定文件中; p:顯示替換成功的行; {COMMANDS}:可以把多個命令括起來,用來處理單個地址或者地址范圍。 sed -n '5,9p;=' sed -n '5,9{p;=}'
高級編輯命令:
h:把模式空間中的內容覆蓋至保持空間中; H:把模式空間中的內容追加至保持空間中; g:把保持空間中的內容覆蓋至模式空間中; G:把保持空間中的內容追加至模式空間中; x:把模式空間中的內容與保持空間中的內容互換; n:覆蓋讀取匹配到的行的下一行至模式空間中; N:追加讀取匹配到的行的下一行至模式空間中; d:刪除模式空間中的行; D:刪除多行模式空間中的所有行;
應用實例
不同的系統環境或sed版本的命令實現有可能有微改動,但是用法基本不變,下列演示基于如下環境中進行:
-
OS: CentOS Linux release 7.2.1511 (Core)
-
sed version: sed (GNU sed) 4.2.2
演示文件1:
[root@IP70-CentOS7 ~]# >>sed '2p' /etc/passwd #打印第二行
[root@IP70-CentOS7 ~]# >>sed -n '2p' /etc/passwd #僅打印第二行
[root@IP70-CentOS7 ~]# >>sed -n '1,4p' /etc/passwd #僅打印第1到第4行(范圍地址)
[root@IP70-CentOS7 ~]# >>sed -n '/root/p' /etc/passwd #僅打印匹配root的行(單地址模式匹配)
[root@IP70-CentOS7 ~]# >>sed -n '2,/root/p' /etc/passwd #僅打印從第2行開始,至匹配root的行(范圍地址)
[root@IP70-CentOS7 ~]# >>sed '/root/a\superman' /etc/passwd #sed-command演示:a:匹配行后追加文本
[root@IP70-CentOS7 ~]# >>sed '/root/i\superman' /etc/passwd #sed-command演示:i:匹配行前插入文本
[root@IP70-CentOS7 ~]# >>sed '/root/c\superman' /etc/passwd #sed-command演示:c:匹配行替換成指定文本
[root@IP70-CentOS7 ~]# >>sed -n 's/root/&superman/p' /etc/passwd #sed-command演示:s:查找root,替換成&superman(&代表引用匹配查找的內容)
[root@IP70-CentOS7 ~]# >>sed 's/root/superman&/g' /etc/passwd #sed-command演示:s:查找替換,對比上個示例,p僅替換每行第一個匹配的文本,g就進行全局匹配
演示文件2:
[root@IP70-CentOS7 ~]# >>sed -n '/^$/=' testfile #sed-command演示:= 顯示行號(^$ 空行)
[root@IP70-CentOS7 ~]# >>sed -n -e '/^$/p' -e '/^$/=' testfile #選項 -e的引用
[root@IP70-CentOS7 ~]# >>sed '/^$/d' testfile #sed-command演示:d 刪除匹配的行
[root@IP70-CentOS7 ~]# >>sed '1,10d' testfile #范圍地址第1至第10行, sed-command: d刪除行
[root@IP70-CentOS7 ~]# >>sed -i.bak 's/^test.*$/deleted/g' testfile #選項-i的應用,如需進行文件修改,強烈建議先備份,即-i.CHAR。(.CHAR為備份文件后綴名,可自定義。)
高級編輯命令
[root@IP70-CentOS7 ~]# >>sed -n 'n;p' testfile.bak #打印偶數行
[root@IP70-CentOS7 ~]# >>sed '1!G;h;$!d' testfile.bak #倒序顯示行,相當于tac命令
[root@IP70-CentOS7 ~]# >>sed '$!N;$!d' testfile.bak
[root@IP70-CentOS7 ~]# >>sed '$!N' testfile.bak
[root@IP70-CentOS7 ~]# >>sed '$!d' testfile.bak
[root@IP70-CentOS7 ~]# >>sed 'G' testfile.bak
[root@IP70-CentOS7 ~]# >>sed 'n;d' testfile.bak
結束語
個人認為相較于grep而言,sed查找匹配行后可進行更多的命令操作,提供的d刪除和s替換功能更是如虎添翼。掌握一項技能在于多用,在理解上述演示的前提下,在實際應用中縱向深挖,與人分享探討。
由于初學Linux,限于本人水平有限,文中難免錯誤紕漏。歡迎各位看官不吝指教、討論相關技術。謝謝。
聯系我:jacky18676887374@aliyun.com
原創文章,作者:昭其,如若轉載,請注明出處:http://www.www58058.com/32451