-
sed 介紹
-
工作原理
-
語法
-
參數選項:-n, -e, -r, -f, -i
-
地址定界
-
編輯命令
-
查找替換
-
空間操作
-
練習
-
參考文檔
sed介紹
sed是一個(stream editor)。 1) :使用sed只能在命令行下輸入編輯命令來編輯文本,然后在屏幕上查看輸出 2) :sed每次只從文件/輸入讀取一行,然后對該行進行指定處理,并輸出結果到屏幕 (除非取消屏幕輸出有未顯示使用打印命令),然后再接著讀入下一行。整個文件像流水一樣被逐行處理然后逐行輸出。
工作原理
sed 有兩個空間(可以理解為內存空間): 1) pattern space 模式空間:根據“模式”及“命令”進行數據處理,類似于“加工車間” 2) hold space 保留空間:臨時存儲數據的空間,類似于“倉庫”(無論處理完的、還是半成品都可以存儲)
sed如何工作?
1) sed讀入一行,存入pattern space; 2) 對pattern space中的內容,按照scripts對pattern space中的內容進行處理(修改、替換、刪除、追加等); 3) 根據需要,與hold space進行數據交換(追加、覆蓋、交換); 4) 根據命令設定,將處理結果輸出到STDOUT; (默認讀入pattern space的行都會自動打印,并且即便已經找到指定行,sed依然會將文本全部過一遍 ) 5) 切換至下一行進行處理;
語法
sed [option]... 'script' inputfile... 其中,script包含了“”、“”、“”、“”的功能,并支持 “”。
參數選項
option參數 | 用途說明 |
---|---|
-n |
暫停pattern space自動打印,與編輯命令中的p結合可以只打印符合條件的數據 |
-e script |
可添加多個腳本,如sed -e 'script1' -e 'script2' file |
-f script-file |
將腳本文件中的內容加入script中執行 |
-i[suffix] |
不用-i時不會修改源文件,添加后綴如.bak,會將源文件備份為file.bak,直接編輯源文件 |
-r |
在script中使用擴展正則表達式ERE |
# 打印passwd文件的第2行內容 sed -n '2p' passwd # 使用script1中的sed命令腳本處理passwd文件 sed -f script1 passwd # 修改passwd文件,并在修改之前將其備份為passwd.bak sed -i.bak 'G' passwd
地址定界
(1) 不給地址:對全文進行處理 (2) 單地址 # : 指定的行 /pattern/ : 被此處模式所能夠匹配到的每一行 $ : 最后一行 (3) 地址范圍 #,# : 第幾行到第幾行 #,+# : 第幾行,并向后加幾行 /pat1/,/pat2/ : 模式1匹配結果所在行(第一個),到 模式2匹配結果所在行(最后一個),包含邊界 #,/pat1/ : 第幾行,到模式1匹配結果所在行(最后一個),包含邊界 addr1, ~N : 匹配到addr1及其以后第一個行號為N的倍數的行,包含邊界 (4) ~:步進 1~2 奇數行 2~2 偶數行
編輯命令
命令標識 | 用途說明 |
---|---|
d | 刪除模式空間匹配的行(delete) |
p | 顯示模式空間中的內容(print) |
a \text | 在行后面追加文本;支持使用\n實現多行追加(append) |
i \text | 在行前面插入文本;支持使用\n實現多行插入(insert) |
c \text | 替換行為單行或多行文本(change) |
w /path/to/somefile | 保存模式匹配的行至指定文件(write) |
r /path/from/somefile | 讀取指定文件的文本至模式空間中匹配到的行后(read) |
= | 為模式空間中的行打印行號 |
! | 模式空間中匹配行取反處理 |
# 在/etc/passwd中root所在行后新增一行,內容為superman sed '/root/a\superman' /etc/passwd sed '/root/a superman' /etc/passwd ### a superman 與a\superman效果相同,但是建議使用\,i和c也有此效果 # 在/etc/passwd中root所在行前新增一行,內容為superman sed '/root/i\superman' /etc/passwd ### 行前 # 將/etc/passwd中root所在行替換為為superman sed '/root/c\superman' /etc/passwd ### 代替行
查找替換
s///:查找替換,支持使用其它分隔符,s@@@,s###替換標記: g: 行內全局替換 p: 顯示替換成功的行 w /PATH/TO/SOMEFILE:將替換成功的行保存至文件中,若文件中有內容會被覆蓋, 但如果使用-e選項而每個命令都保存到同一個文件則是追加的形式
# 將passwd中的所有root替換成superman,所有wangcai替換成xiaobai,并將替換成功的行記錄到change文件中 sed -e 's/root/superman/gw /testdir/change' -e 's/wangcai/xiaobai/gw /testdir/change' /etc/passwd
空間操作
操作標識 | 用途說明 |
---|---|
h | 把模式空間中的內容覆蓋至保持空間中(copy pattern space to hold space) |
H | 把模式空間中的內容追加至保持空間中(append pattern space to hold space) |
g | 從保持空間取出數據覆蓋至模式空間(copy hold space to pattern space) |
G | 從保持空間取出內容追加至模式空間(append hold space to pattern space) |
x | 把模式空間中的內容與保持空間中的內容進行互換(Exchange the contents of pattern space and hold space) |
n | 讀取匹配到的行的下一行覆蓋至模式空間(read the next line of input into pattern space) |
N | 追加匹配到的行的下一行至模式空間(append the next line of input into pattern space) |
d | 刪除模式空間中的行(Delete pattern space. immediately start next cycle.) |
D | 刪除當前模式空間開端至\n的內容(不再傳至標準輸出),放棄之后的命令,但是對剩余模式空間重新執行sed |
# 在每一行后面增加一空行 sed G file # 在每一行后增加兩個空行 sed 'G;G' file # 顯示所有奇數行 sed 'n;d' file # 顯示所有偶數行 sed -n 'n;p' file # 刪除所有空行,并在每一行后面增加一個空行 sed '/^$/d;G' file # 給每一個非空行編號,并只將非空行的行號及行內容到一行 sed '/./=' file | sed '/./N; s#\n# #' # 取passwd文件的最后一行 sed '$!d' passwd sed -n '$p' passwd # 去掉文件中的空行,并為每一行后加一空行分隔 sed '/^$/d;G' FILE # 將passwd文件逆序展示(同于 tac ) sed '1!G;h;$!d' /etc/passwd #--------------------------------------------------------------------------------------------------------------------------- # 命令解析: # 1)若當前行不是第一行,則從hold space取內容追加到 pattern space的內容之后;第一行不操作; # 2)將pattern space中的內容替換hold space中的現有內容; # 3)若當前行不是最后一行,則清空pattern space; # 示例說明: # 文件共五行,內容分別為1、2、3、4、5(下文解釋每個數字代表一行) # 1)第一行,直接放入hold space,清空pattern space; [patternspace:null ; holdspace:1 ] # 2) 第二行,取holdspace內容追加到patternspace,替換holdspace,清空patternspace;[patternspace:null ; holdspace:2 1 ] # 3) 第三行,取holdspace內容追加到patternspace,替換holdspace,清空patternspace;[patternspace:null ; holdspace:3 2 1 ] # 4) 第四行,取holdspace內容追加到patternspace,替換holdspace,清空patternspace;[patternspace:null ; holdspace:4 3 2 1 ] # 5) 第五行,取holdspace內容追加到patternspace,替換holdspace; [patternspace:5 4 3 2 1; holdspace:5 4 3 2 1] # 最后,命令執行結束,默認輸出打印 “pattern space” 的內容。 #--------------------------------------------------------------------------------------------------------------------------- # # 在這里,我原來沒有認真看幫助手冊,因此對于默認打印有一個錯誤的認知(如下圖中的結論所示所示), # “正確的” 結論應該是:自動打印是在命令執行完后,打印pattern space的內容。 # # 【關于n】 # If auto-print is not disabled,print the pattern space,then,regardless,replace the pattern space with the next line of input. # If there is no more input then `sed' exits without processing any more commands. # 【關于錯誤的重新解讀】 # 下圖中第3張之所以打印出第一行,是因為n的同時又未禁用掉自動打印。 #---------------------------------------------------------------------------------------------------------------------------
練習
1、刪除/etc/grub2.cfg文件中所有以空白開頭的行行首的空白字符
sed -r 's@^[[:space:]]+@@' /etc/grub2.cfg # 注意:+是必須的,因為空白開頭的空白字符的個數 ≥ 1
2、刪除/etc/fstab文件中所有以#開頭,后面至少跟一個空白字符的行的行首的#和空白字符
sed 's@^#[[:space:]]\+@@' /etc/fstab
3、在/root/install.log每一行行首增加#號
sed -r 's@(.*)@#\1@g' /root/install.logsed 's@^@#@' /root/install.log
4、在/etc/fstab文件中不以#開頭的行的行首增加#號
sed 's@^[^#]@#@' /etc/fstab sed -r 's@(.*)@#\1@g' /etc/fstab
5、處理/etc/fstab路徑,使用sed命令取出其目錄名和基名
echo /etc/sysconfig/ |sed -r 's#[^/]+/?$##' echo /etc/sysconfig/ |sed -r 's#^(.*/)([^/]+/?)$#\1#' ### 取目錄名 echo /etc/sysconfig/ |sed -r 's#^(.*/)([^/]+/?)$#\2#' ### 取基名
6、利用sed 取出ifconfig命令中本機的IPv4地址
ifconfig | sed -n 2p | sed -r 's@inet (.*) net.*@\1@'
7、統計centos安裝光盤中Package目錄下的所有rpm文件的以.分隔倒數第二個字段的重復次數
ls *.rpm |sed -r 's#.*\.(.*)\.rpm$#\1#'|sort|uniq -c ### sort 默認按照ASCII碼表先后排序 ls *.rpm |rev |cut -d. -f2 |rev|sort |uniq -c
參考
[1] 了解sed的工作原理(pattern space 和 hold space
[2] sed流編輯器
[3] SED單行腳本快速參考
原創文章,作者:taobaibai,如若轉載,請注明出處:http://www.www58058.com/33881