1.sed簡介
sed是一種流編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲“模式空間”(pattern space),接着用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。然後讀入下行,執行下一個循環。如果沒有使諸如‘D’的特殊命令,那會在兩個循環之間清空模式空間,但不會清空保留空間。這樣不斷重複,直到文件末尾。文件內容並沒有改變,除非你使用重定向存儲輸出。
功能:主要用來自動編輯一個或多個文件,簡化對文件的反覆操作,編寫轉換程序等
grep:單純的文本查找匹配,無法對數據進行修改
sed:可以文本查找,也可以對文本編輯修改(替換、刪除)
awk:格式化複雜的文本
格式:
1、sed [options] ‘command’ file(s) command=條件和處理動作,若command中包含變量,要用”command”
2、sed [options] -f scriptfile file(s)
常用選項:
-n:不輸出模式空間內容到屏幕,即不自動打印
-e: 多點編輯
-f:/PATH/SCRIPT_FILE: 從指定文件中讀取編輯腳本
-r: 支持使用擴展正則表達式
-i.bak: 備份文件並原處編輯
2.選項用法
準備文件:cp /etc/passwd /data/
1.-i:修改源文件,後面一定要接文件cat
[root@Centos7 data]#sed -i '2d' passwd
錯誤寫法:
[root@Centos7_101 data]#cat -n passwd | sed -i '2d'
sed: no input files
2.-i.bak:修改源文件之前,備份以.bak結尾
[root@Centos7 data]#sed -i.bak '2d' passwd
-f:調用文本
[root@Centos7 data]#sed -r '/^[^#]/s/[[:alpha:]]/\u&/g' /etc/fstab
[root@Centos7 data]#vim sed.script
[root@Centos7 data]#cat sed.script
/^[^#]/s/[[:alpha:]]/\u&/g
[root@Centos7 data]#sed -r -f sed.script /etc/fstab
[root@Centos7 data]#cat sed.script
2s/.*inet //;s/ netmask.*//p
[root@Centos7 data]#ifconfig ens33 | sed -rnf sed.script
172.16.34.101
-e:多命令編輯
[root@Centos7_101 data]#ifconfig ens33 | sed -rne '2s/.* inet //p' -e 's/ netmask.*//p' -e 's/172/192/p'
172.20.34.101 netmask 255.255.0.0 broadcast 172.20.255.255 #這是第一條命令執行的結果
172.20.34.101 #這是在第一條結果的基礎上執行後的結果
192.20.34.101 #這是在第2條結果基礎上執行後的結果
等價於用;把命令隔開
[root@Centos7_101 data]#ifconfig ens33 | sed -rne '2s/.* inet //p;s/ netmask.*//p;s/172/192/p'
3.條件地址
- 表示全部打印在屏幕上
#sed -n ‘p’ passwd
2.打印指定行,打印第2行
[root@Centos7 data]#sed -n '2p' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
[root@Centos7 data]#ifconfig ens33 | sed -n '2p'
inet 172.16.34.101 netmask 255.255.0.0 broadcast 172.16.255.255
3.顯示最後一行
[root@Centos7 data]#sed -n '$p' passwd
chen:x:1000:1000:chen:/home/chen:/bin/bash
4.指定範圍行,’1,3p’:第1到第3行
[root@Centos7 data]#sed -n '1,3p' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
5.正則表達匹配行,’/正則表達式/’,選項-r支持擴展正則表達式。
[root@Centos7 data]#sed -n '/^U/p' /etc/fstab 顯示U開頭的行
UUID=ba708318-e653-437f-b7e7-2c81ae7cbbe2 / xfs defaults 0 0
UUID=12984512-ec20-4b99-a000-34b8ba546a14 /boot xfs defaults 0 0
UUID=9c9b025f-487c-42cd-9bec-6f9c582cdbe5 /data xfs defaults 0 0
UUID=210c8f6a-8a2a-40cc-bd3b-6cb106159332 swap swap defaults 0 0
6.打印匹配/dev/sd,需要加轉義符\/dev\/sd
[root@Centos7 data]#df -h | sed -n '/\/dev\/sd/p'
/dev/sda2 20G 4.0G 16G 20% /
/dev/sda5 27G 33M 27G 1% /data
/dev/sda1 1014M 165M 850M 17% /boot
7.打印第1行,和第1行後面的3行
[root@Centos7 data]#cat -n passwd | sed -n '1,+3p'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
8.從第3行開始,到以f開頭的範圍打印出來
#sed -n '3,/^f/p' passwd
9.匹配範圍,’/正則表達式/,/正則表達式/’
10.打印奇數’1~2’和偶數’2~2’行,1~3,從1開始隔3個數
[root@Centos7 data]#seq 10|sed -n '1~2p'
1
3
5
7
9
[root@Centos7 data]#seq 10|sed -n '2~2p'
2
4
6
8
10
總結:條件大致分爲:指定行、範圍行、正則表達式、範圍正則表達式、行加正則表達式
4.處理動作
編輯命令:
d: 刪除模式空間匹配的行,並立即啓用下一輪循環
p:打印當前模式空間內容,追加到默認輸出之後
a []text:在指定行後面追加文本,支持使用\n實現多行追加
i []text:在行前面插入文本
c []text:替換行爲單行或多行文本
w /path/somefile: 保存模式匹配的行至指定文件
r /path/somefile:讀取指定文件的文本至模式空間中匹配到的行後
=: 爲模式空間中的行打印行號
!:模式空間中匹配行取反處理
s///:查找替換,支持使用其它分隔符,s@@@,s###
替換標記:
g: 行內全局替換
p: 顯示替換成功的行
w /PATH/TO/SOMEFILE:將替換成功的行保存至文件中
d:刪除
1.刪除指定行
[root@Centos7 data]#cat -n passwd | sed '2d'
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
……
[root@Centos7 data]#cat -n passwd | sed '2,20d'
1 root:x:0:0:root:/root:/bin/bash
21 gluster:x:995:992:GlusterFS daemons:/var/run/gluster:/sbin/nologin
[root@Centos7 data]#cat -n passwd | sed -n ‘2~2d;p’
命令解析:第一行是否滿足’2~2d’,不滿足,繼續匹配下一條命令p,滿足,然後打印到屏幕上
繼續處理下一行,第二行滿’2~2d’,滿足,就刪除,下一條命令就不用管了,繼續依次執行後面行
把偶數行刪掉,奇數行打印出來,等同:#sed -n ‘1~2p’
2.用正則表達式匹配到的行刪掉
[root@Centos7 data]#sed '/^#/d' /etc/fstab
3.刪除空白行
#sed '/^$/d' demo.txt
a:行後追加
1.指定行添加
[root@Centos7 data]#cat -n passwd | sed '1,20a new line'
1 root:x:0:0:root:/root:/bin/bash
new line
2 bin:x:1:1:bin:/bin:/sbin/nologin
new line
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
a後面加,告訴a,\後面的所有東西就是要追加的,包括空格
[root@Centos7 data]#cat -n passwd | sed '1,20a\ new line'
1 root:x:0:0:root:/root:/bin/bash
new line
2 bin:x:1:1:bin:/bin:/sbin/nologin
new line
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
new line
2.添加多行字符串間用\n換行即可
[root@Centos7 data]#cat -n passwd | sed '1,20a\ new line1\n new line2'
1 root:x:0:0:root:/root:/bin/bash
new line1
new line2
2 bin:x:1:1:bin:/bin:/sbin/nologin
new line1
new line2
3.匹配正則表達式
[root@Centos7 data]#sed '/^# Source .*/a\hello world' /root/.bashrc
i:前面行追加(語法和a同理)
c:滿足條件行替換(語法和a同理)
[root@Centos7 data]#sed '/^# Source .*/c\ hello world' /root/.bashrc
w:滿足條件行保存到指定文件
1.指定行
[root@Centos7 data]#cat -n passwd | sed -n '1,3w /data/f3'
[root@Centos7 data]#cat f3
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
2.正則表達式匹配行
[root@Centos7 data]#sed -n '/^U/w /data/f2' /etc/fstab
[root@Centos7 data]#cat f2
UUID=ba708318-e653-437f-b7e7-2c81ae7cbbe2 / xfs defaults 0 0
UUID=12984512-ec20-4b99-a000-34b8ba546a14 /boot xfs defaults 0 0
UUID=9c9b025f-487c-42cd-9bec-6f9c582cdbe5 /data xfs defaults 0 0
UUID=210c8f6a-8a2a-40cc-bd3b-6cb106159332 swap swap defaults 0 0
r:滿足條件行後面添加指定文件內容
[root@Centos7 data]#cat addfile
cjx:x:222:2222:cjx:/sbin:/sbin/nologin
[root@Centos7 data]#cat passwd | sed '1r /data/addfile'
root:x:0:0:root:/root:/bin/bash
cjx:x:222:2222:cjx:/sbin:/sbin/nologin addfile內容添加到第1行後面
=:滿足條件行前面行顯示行號
[root@Centos7 data]#sed '1,3=' passwd
1
root:x:0:0:root:/root:/bin/bash
2
bin:x:1:1:bin:/bin:/sbin/nologin
3
!:取反顯示行號,效果與=相反
s///:替換,達到增、刪、改功能(重點)
#who am i | awk '{print $5}'|sed 's/[()]//g'
172.16.34.100
[root@Centos7 data]#sed 's/root/ROOT/' passwd
ROOT:x:0:0:root:/root:/bin/bash 只替換一個root
要想全局替換
[root@Centos7 data]#sed 's/root/ROOT/g' passwd
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
還可以指定第2個root,再開始替換
[root@Centos7 data]#sed 's/root/ROOT/2g' passwd
root:x:0:0:ROOT:/ROOT:/bin/bash
正則表達式分組:-r 表示支持擴展正則表達式 -n表示關掉默認打印,g表示全局替換,p表示滿條件的打印出來
\1表示正則表達式的一個分組,分組後面加er
rooter:x:0:0:rooter:/rooter:/bin/bash
[root@Centos7 data]#sed -rn ‘s/(root)/\1er/gp’ passwd
operator:x:11:0:operator:/rooter:/sbin/nologin
例子1
[root@Centos7 data]#cat /etc/default/grub | sed -r 's/(quiet)/\1 net.ifnames=0/'
[root@Centos7 data]#cat /etc/default/grub | sed -r 's/(LINUX.*)"/\11 net.fnames=0"/'
還可以先查找滿足條件的行,下例先用正則表達式匹配LINUX的行
[root@Centos7 data]#cat /etc/default/grub | sed -r '/LINUX/s/(.*)$"/\11 net.fnames=0"/'
[root@Centos7 data]#cat /etc/default/grub | sed -r '/LINUX/s/"$/ net.fnames=0"/'
例子2,用seq提取ip
[root@Centos7 data]#ifconfig ens33 | sed -n '2p'
inet 172.16.34.101 netmask 255.255.0.0 broadcast 172.16.255.255
方法1:把ip前後刪掉,”;”可以添加多條命令
[root@Centos7 data]#ifconfig ens33 | sed -rn '2s/.*inet //;s/ netmask.*//p'
172.16.34.101
方法2:用分組實現
[root@Centos7 data]#ifconfig ens33 | sed -rn '2s/(.*inet )(.*)( netmask.*)/\2/p'
172.16.34.101
例子3:截取基名
[root@Centos7 data]#echo "/etc/sysconfig/network-scripts/" | sed -r 's#(^.*/)([^/]+/?)#\2#'
network-scripts/
截取目錄名
#echo /etc/rc.d/init.d/functions | sed -rn 's#(/.*/)[[:alnum:]]+/?#\1#p'
例子4:非#開頭的,加上#
[root@Centos7 data]#sed -r '/^[^#]/s/(.*)/#\1/' /etc/fstab
[root@Centos7 data]#sed -r '/^[^#]/s/(.*)/#&/' /etc/fstab
例子5:轉成大寫字母 \u:大寫,\l:小寫
[root@Centos7 data]#sed -r '/^[^#]/s/[[:alpha:]]/\u&/g' /etc/fstab
例子6:獲取主版本號
[root@Centos7 data]#cat /etc/redhat-release | sed -r 's/(^.* )([[:digit:]]+)(.*)/\2/'
7
5.練習
sed示例
sed ‘2p’ /etc/passwd
sed –n ‘2p’ /etc/passwd
sed –n ‘1,4p’ /etc/passwd
sed –n ‘/root/p’ /etc/passwd
sed –n ‘2,/root/p’ /etc/passwd 從2行開始
sed -n ‘/^$/=’ file 顯示空行行號
sed –n –e ‘/^$/p’ –e ‘/^$/=’ file
sed ‘/root/a\superman’ /etc/passwd行後
sed -n '/root/p;/root/a\superman' /etc/passwd
sed ‘/root/i\superman’ /etc/passwd 行前
sed ‘/root/c\superman’ /etc/passwd 代替行
sed ‘/^$/d’ file
sed ‘1,10d’ file
nl /etc/passwd | sed ‘2,5d’
nl /etc/passwd | sed ‘2a tea’
sed 's/test/mytest/g' example
sed –n ‘s/root/&superman/p’ /etc/passwd 單詞後
sed –n ‘s/root/superman&/p’ /etc/passwd 單詞前
sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’ pets
sed –i.bak ‘s/dog/cat/g’ pets