1、sed介紹
sed(Stream EDitor),是一種行編輯工具,它一次處理一行內容。處理時,把當前匹配到的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接著用sed命令對這些數據做出相應的增刪改查操作,處理完成后,默認輸出至屏幕,而未被匹配到的行也將默認輸出至屏幕。而原來的文件內容并沒有發生改變,除非使用重定向存儲輸出。
2、sed用法
<1>語法格式
sed [option]… 'addressCOMMAND' inputfile…
<2>[option]
-n | 不輸出模式空間和未匹配到的數據 |
-e | 多點編輯 |
-r | 支持使用擴展的正則表達式 |
-i | 原處編輯 |
注:雖然可通過sed -i.bak '4,$d' /tmp/fstab類似的方式處理/tmp/fstab文件,而且會在/tmp目錄下生成fstab.bak備份的文件,但依然不建議在生產生活中使用
[root@centos7 ~]# sed -i.bak '4,$d' /tmp/fstab [root@centos7 ~]# ls /tmp/ fstab fstab.bak functions
<3>address
不給地址 | 對全文進行搜索 |
單地址 | |
# | 指定的行 |
/pattern/ | 被模式匹配到的每一行 |
地址范圍 | |
#,# | 指定的行到指定的行 |
#,+# | 指定的行到下幾行 |
/pat1/,/pat2/ | 第一次被某模式匹配到的行到最后一次被某模式匹配到的行 |
#,/pat1/ | 第幾行到最后一次被某模式匹配到的行 |
步進 | |
1~2 | 奇數行 |
2~2 | 偶數行 |
<4>COMMAND
d:刪除模式空間匹配到的行
p:顯示模式空間中的行
注:此命令一般與-n選項同用,否則匹配到的內容會顯示倆次
a \text\:在行后面追加文本,支持使用\n實現多行追加
i \text\:在行前面插入文本,支持使用\n實現多行插入
c \text\:替換為單行或多行文本
w /path/to/somefile:保存模式匹配到的行至指定文件,一般也會與-n同用
[root@centos7 ~]# sed -n '/UUID/w /tmp/fstab.tmp' /etc/fstab [root@centos7 ~]# cat /tmp/fstab.tmp UUID=cb86b5f6-3ea1-48b6-ad1d-5a77cf565d5b /boot xfs defaults 0 0
r /path/from/somefile
[root@centos7 ~]# cat a haha [root@centos7 ~]# sed '/Kernel/r a' /etc/issue \S Kernel \r on an \m haha
s///:查找替換,支持使用其它分隔符,s@@@,s###
g:全局替換
針對以上知識點,做以下加強練習
1、刪除/etc/grub2.conf文件中所有以空白開頭的行行首的空白字符
[root@centos7 ~]# sed -r 's@^[[:space:]]\+@@' /etc/grub2.cfg
2、刪除/etc/fstab文件中所有以#開頭,后面至少跟一個空白字符的行的行首的#和空白字符
[root@centos7 ~]# sed -r 's@^#[[:space:]]+@@' /etc/fstab
3、在/etc/fstab每一行行首增加#號
[root@centos7 ~]# sed 's@^@#&@' /etc/fstab
或者
[root@centos7 ~]# sed 's@^.*@#&@' /etc/fstab
注意:此處不可寫成sed 's@^(.*)@#$@' /etc/fstab,這是錯誤的,此處錨定的是(),而不是行首
[root@centos7 ~]# cat > f1 () a b ^C [root@centos7 ~]# sed 's@^(.*)@#&@' f1 #() a b
4、在/etc/fstab文件中不以#開頭的行的行首增加#號
[root@centos7 ~]# sed 's@^[^#]@#&@' /etc/fstab
5、處理/etc/fstab路徑,使用sed命令取出其目錄名和基名
[root@centos7 ~]# echo /etc/fstab | sed -r 's@(.*/)([^/]+/?$)@\1@' /etc/ [root@centos7 ~]# echo /etc/fstab | sed -r 's@(.*/)([^/]+/?$)@\2@' fstab
6、利用sed 取出ifconfig命令中本機的IPv4地址
[root@centos7 ~]# ifconfig | sed -n '2p' | sed -e 's@.*inet[[:space:]]@@' -e 's@[[:space:]].*@@'
或者
[root@centos7 ~]# ifconfig | sed -n '2p' | sed -r 's@.*inet[[:space:]](.*)[[:space:]]net.*@\1@' 10.1.0.17
當然,如果使用cut就簡單多了
[root@centos7 ~]# ifconfig | sed -n '2p' | tr -s ' ' | cut -d' ' -f3 10.1.0.17
7、統計centos安裝光盤中Package目錄下的所有rpm文件的以.分隔倒數第二個字段的重復次數
[root@centos7 Packages]# ls | grep "rpm$" | sed -e 's@.rpm$@@' -e 's@.*\.@@' | sort | uniq -c 2000 i686 2938 noarch 4069 x86_64
或者
[root@centos7 Packages]# ls | grep "rpm$" | sed -r 's@.*\.(.*)\.rpm@\1@' | sort | uniq -c 2000 i686 2938 noarch 4069 x86_64
注意常見的錯誤
使用正則表達式注意.的轉義
使用擴展正則表達式注意分組時要加-r
再或者
[root@centos7 Packages]# ls | grep "rpm$" | rev | cut -d. -f2 | sort | uniq -c 4069 46_68x 2000 686i 2938 hcraon
總結:個人認為,sed命令是grep命令的延伸,雖然有些功能比如篩選同樣的行時,倆者都可實現,但是如果數據量很大的話,相比而言,grep是更加方便的。所以grep篩選數據,sed再處理數據,這樣無疑是最好的結果。至于cut、tr等命令,同樣可以處理很多grep和sed要處理的問題,像篩選特定的字段,所以也是非常靈活的,要勤加練習,才能掌握的游刃有余。
原創文章,作者:mfwing,如若轉載,請注明出處:http://www.www58058.com/32845