Linux三剑客之-sed
描述
sed - stream editor for filtering and transforming text;
sed 是 stream editor 的缩写,即流编辑器,默认读取整个文件并对其中的每一行进行修改;
使用方式
-
命令语法
sed [选项] '[行定位符]指令' 文件名
命令 | sed [选项] '[行定位符]指令'
-
常用选项
选项 描述 -h 显示帮助信息 -n 仅显示处理后的行信息 -r 定位符中使用扩展正则表达式 -i 直接将处理后的信息写入文件 -e 允许处理多个’定位符+指令’ -
常用指令
选项 描述 p 打印定位行信息 d 删除定位行信息 s 替换定位行指定信息 c 替换定位行整行信息 = 打印当前行行号信息 a 向定位行下一行添加指定信息 i 向定位行上一行添加指定信息 r 向定位行后添加r读取的指定文件信息 w 将定位行写入w指定的文件 n 将定位行的下一行进行处理 -
常用定位符
- 1,3 – 第1-3行
- 1~2 – 从第1行开始,每隔一行进行处理,即奇数行
- 2,3+ – 从第2开始及后3行,即2-5行
- 3! – 非第3行的其他行
- /正则表达式/ – 匹配正则表达式的行
- /正则表达式1/,/正则表达式2/ – 从匹配正则表达式1到匹配正则表达式2的行
-
示例
测试文件信息[root@centos-36_2 tmp]# cat test_sed 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 7 CoreIpAddress: 172.16.36.218 8 CoreName: broad_Aux [root@centos-36_2 tmp]#
- 不加任何选项和定位信息直接运行(默认处理所有行)
[root@centos-36_2 tmp]# sed 'p' test_sed 1 The Redis server has been running, ignore this step. 1 The Redis server has been running, ignore this step. 2 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 7 CoreIpAddress: 172.16.36.218 7 CoreIpAddress: 172.16.36.218 8 CoreName: broad_Aux 8 CoreName: broad_Aux [root@centos-36_2 tmp]#
- 定位奇数行(可以看出奇数行打印两遍)
[root@centos-36_2 tmp]# sed '1~2p' test_sed 1 The Redis server has been running, ignore this step. 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 7 CoreIpAddress: 172.16.36.218 7 CoreIpAddress: 172.16.36.218 8 CoreName: broad_Aux [root@centos-36_2 tmp]#
- 加-n选项仅显示定位行(可以看到仅显示第3,6行)
[root@centos-36_2 tmp]# sed -n '3p;6p' test_sed 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: [root@centos-36_2 tmp]#
- 通过正则表达式定位指定行(包含NOT/NOt/NoT/Not的行)
[root@centos-36_2 tmp]# sed -n '/N[Oo][Tt]/p' test_sed 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: [root@centos-36_2 tmp]#
- 通过正则表达式定位范围行(以’ 3’开头到以’REQ’结尾的行)
[root@centos-36_2 tmp]# sed -n '/^ 3/,/REQ$/p' test_sed 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ [root@centos-36_2 tmp]#
- 通过扩展正则表达式定位行(包含ip地址的行)
[root@centos-36_2 tmp]# sed -rn '/([0-9]{1,3}\.){3}[0-9]{1,3}/p' test_sed 7 CoreIpAddress: 172.16.36.218 [root@centos-36_2 tmp]#
- 删除定位行(删除包含NOTIFY的行)
[root@centos-36_2 tmp]# sed '/NOTIFY/d' test_sed 1 The Redis server has been running, ignore this step. 2 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 7 CoreIpAddress: 172.16.36.218 8 CoreName: broad_Aux [root@centos-36_2 tmp]#
- 整行替换(包含Ip的行,整体替换)
[root@centos-36_2 tmp]# sed -n '/Ip/c CoreIpAddress: 1.1.1.1' test_sed CoreIpAddress: 1.1.1.1 [root@centos-36_2 tmp]#
- 所有行查找替换一次指定字符(将所有行的第一个数字替换为NUM)
[root@centos-36_2 tmp]# sed 's/[0-9]/NUM/' test_sed NUM The Redis server has been running, ignore this step. NUM NUM 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info NUM 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ NUM NUM 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: NUM CoreIpAddress: 172.16.36.218 NUM CoreName: broad_Aux [root@centos-36_2 tmp]#
- 所有行查找替换所有指定字符(将所有行的数字替换为NUM)
[root@centos-36_2 tmp]# sed 's/[0-9]/NUM/g' test_sed NUM The Redis server has been running, ignore this step. NUM NUM NUMNUMNUMNUM-NUMNUM-NUMNUM NUMNUM:NUMNUM:NUMNUM-tor.py-NUMNUMNUM-NOTIFY: Received info NUM NUMNUMNUMNUM-NUMNUM-NUMNUM NUMNUM:NUMNUM:NUMNUM-kln.py-NUMNUMNUM-INFO: Received NotifyREQ NUM NUM NUMNUMNUMNUM-NUMNUM-NUMNUM NUMNUM:NUMNUM:NUMNUM-tor.py-NUMNUMNUM-NOTIFY: RPD IRA-RSP CORE-ID TLVs: NUM CoreIpAddress: NUMNUMNUM.NUMNUM.NUMNUM.NUMNUMNUM NUM CoreName: broad_Aux [root@centos-36_2 tmp]#
- 指定行号替换指定字符(将第3行的NOTIFY替换为ERROR)
[root@centos-36_2 tmp]# sed -n '3s/NOTIFY/ERROR/p' test_sed 3 2021-07-29 11:31:34-tor.py-478-ERROR: Received info [root@centos-36_2 tmp]#
- 过滤行替换指定字符(将包含CoreIp的行中的IP地址替换为1.1.1.1)
[root@centos-36_2 tmp]# sed -rn '/CoreIp/s/([0-9]{1,3}\.){3}[0-9]{1,3}/1\.1\.1\.1/p' test_sed 7 CoreIpAddress: 1.1.1.1 [root@centos-36_2 tmp]#
- 替换指定字符时
&
符号的作用(替换后字符中的&
符即替换前的字符)
[root@centos-36_2 tmp]# sed -n 's/INFO/&(info)/p' test_sed 4 2021-07-29 13:15:15-kln.py-478-INFO(info): Received NotifyREQ [root@centos-36_2 tmp]# [root@centos-36_2 tmp]# sed -n 's/k.*\.py/&(file)/p' test_sed 4 2021-07-29 13:15:15-kln.py(file)-478-INFO: Received NotifyREQ [root@centos-36_2 tmp]#
- 打印搜索行的行号(搜索含’[0-9]{3}.'的行并打印其行号)
[root@centos-36_2 tmp]# sed -nr '/[0-9]{3}\./p' test_sed 7 CoreIpAddress: 172.16.36.218 [root@centos-36_2 tmp]# sed -nr '/[0-9]{3}\./=' test_sed 7 [root@centos-36_2 tmp]#
- 打印文档总行数(
$=
表示最后一行行号即文档总行数)
[root@centos-36_2 tmp]# sed -n '$=' test_sed 8 [root@centos-36_2 tmp]#
- 在指定行的上一行插入信息(搜索包含’Core’的行,在上方插入信息)
[root@centos-36_2 tmp]# sed '/Core/i test line' test_sed 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: test line 7 CoreIpAddress: 172.16.36.218 test line 8 CoreName: broad_Aux [root@centos-36_2 tmp]#
- 在指定行的下一行插入信息(搜索包含’Core’的行,在下方插入信息)
[root@centos-36_2 tmp]# sed '/Core/a test line' test_sed 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 7 CoreIpAddress: 172.16.36.218 test line 8 CoreName: broad_Aux test line [root@centos-36_2 tmp]#
- 读取文件插入指定行后(定位含IpAddress的行将’addline’文档信息插入其后)
[root@centos-36_2 tmp]# cat addline AAA BBB [root@centos-36_2 tmp]# sed '/IpAddress/r addline' test_sed 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 7 CoreIpAddress: 172.16.36.218 AAA BBB 8 CoreName: broad_Aux [root@centos-36_2 tmp]#
- 过滤指定行后写入文件(定位含’NO/No’的行并写入文件’no_sed’)
[root@centos-36_2 tmp]# sed -n '/N[oO]/w no_sed' test_sed [root@centos-36_2 tmp]# cat no_sed 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: [root@centos-36_2 tmp]#
- 过滤指定行的下一行进行处理(对过滤行的下一行进行删除和替换)
[root@centos-36_2 tmp]# sed '/NOTIFY/{n;d;}' test_sed 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 8 CoreName: broad_Aux [root@centos-36_2 tmp]# [root@centos-36_2 tmp]# sed -n '/NOTIFY/{n;s/o/RRR/p;}' test_sed 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NRRRtifyREQ 7 CRRRreIpAddress: 2.2.2.2 [root@centos-36_2 tmp]#
- sed处理后的信息直接写入源文件(默认不会修改源文件,-i选项会直接修改源文件,i.bak在修改源文件的同时生成备份文件)
[root@centos-36_2 tmp]# cat test_sed 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 7 CoreIpAddress: 172.16.36.218 8 CoreName: broad_Aux [root@centos-36_2 tmp]# [root@centos-36_2 tmp]# sed -ri.bak '/IpAddress/s/([0-9]{1,3}\.){3}[0-9]{1,3}/2\.2\.2\.2/' test_sed [root@centos-36_2 tmp]# cat test_sed 1 The Redis server has been running, ignore this step. 2 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ 5 6 2021-07-29 13:15:55-tor.py-550-NOTIFY: RPD IRA-RSP CORE-ID TLVs: 7 CoreIpAddress: 2.2.2.2 8 CoreName: broad_Aux [root@centos-36_2 tmp]# [root@centos-36_2 tmp]# ll | grep test_sed \-rw-r--r-- 1 root root 325 8月 11 17:13 test_sed \-rw-r--r-- 1 root root 331 8月 11 17:12 test_sed.bak [root@centos-36_2 tmp]#
- 同时过滤行进行多点处理(同时将第3行和第4行分别进行替换;同时对第3行进行两项替换)
[root@centos-36_2 tmp]# sed -ne '3p' -e '4p' test_sed 3 2021-07-29 11:31:34-tor.py-478-NOTIFY: Received info 4 2021-07-29 13:15:15-kln.py-478-INFO: Received NotifyREQ [root@centos-36_2 tmp]# [root@centos-36_2 tmp]# sed -ne '3s/NOTIFY/INFO/p' -e '4s/INFO/ERROR/p' test_sed 3 2021-07-29 11:31:34-tor.py-478-INFO: Received info 4 2021-07-29 13:15:15-kln.py-478-ERROR: Received NotifyREQ [root@centos-36_2 tmp]# [root@centos-36_2 tmp]# sed -ne '3s/NOTIFY/ABC/' -e '3s/info/OOO/p' test_sed 3 2021-07-29 11:31:34-tor.py-478-ABC: Received OOO [root@centos-36_2 tmp]#
- 通过重定向方式使用sed(对于sed使用方法一样,只是数据来源不一样)
[root@centos-36_2 tmp]# ll | grep test \-rw-r--r-- 1 root root 436 8月 6 13:54 test_grep \-rw-r--r-- 1 root root 325 8月 11 17:13 test_sed \-rw-r--r-- 1 root root 331 8月 11 17:12 test_sed.bak [root@centos-36_2 tmp]# ll | grep test | sed -n '2p' \-rw-r--r-- 1 root root 325 8月 11 17:13 test_sed [root@centos-36_2 tmp]#