文本处理工具——sed进阶
Posted wang618
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文本处理工具——sed进阶相关的知识,希望对你有一定的参考价值。
一sed的搜索替代
(一)常见的和替代相关的选项
搜索替代,和vim的写法很像
s///:查找替换,支持使用其它分隔符,[email protected]@@,s###
p: 显示替换成功的行,就是打印。
w /PATH/TO/SOMEFILE :将替换成功的行保存至文件中
替换标记:
g: 行内全局替换和博客园里面的替换全部是一样的效果
注意搜索最好不要使用斜线/,因为linux系统里面有很多斜线,比如目录或者文件路径。
前面搜索的是模式,使用正则表达式$,后面替换的内容就不要了。
(1)s///:查找替换,支持使用其它分隔符,[email protected]@@,s###
把/bin/bash结尾的行替换为/sbin/nologin结尾
[[email protected] ~]# sed ‘[email protected]/bin/[email protected]/sbin/[email protected]‘ /etc/passwd
root:x:0:0:root:/root:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
wang:x:1000:1000:wang:/home/wang:/sbin/nologin
注意没有加-i都只是测试而已,没有真正修改文件里面的内容
在ansible里面也是一样,有测试和真正执行。
[[email protected] ~]# cat /etc/passwd -n 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 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 sync:x:5:0:sync:/sbin:/bin/sync 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 halt:x:7:0:halt:/sbin:/sbin/halt 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 operator:x:11:0:operator:/root:/sbin/nologin 11 games:x:12:100:games:/usr/games:/sbin/nologin 12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13 nobody:x:99:99:Nobody:/:/sbin/nologin 14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin 15 dbus:x:81:81:System message bus:/:/sbin/nologin 16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin 17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin 19 wang:x:1000:1000:wang:/home/wang:/bin/bash
(2) -r: 支持使用扩展正则表达式
-r, --regexp-extended
use extended regular expressions in the script.
1)
(/bin/bash)$表示(/bin/bash)$行尾是/bin/bash
[[email protected] ~]# sed -r ‘[email protected](/bin/bash)[email protected]######@‘ /etc/passwd root:x:0:0:root:/root:###### bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin wang:x:1000:1000:wang:/home/wang:######
2)使用正则表达式里面的后向引用
在bash的前面追加了###
文件未修改内容
[[email protected] ~]# cat /etc/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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin wang:x:1000:1000:wang:/home/wang:/bin/bash
对第1行修改,忽略了命令
[[email protected] ~]# sed -r ‘[email protected](/bin/bash)[email protected]######\\[email protected]‘ /etc/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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin wang:x:1000:1000:wang:/home/wang:######/bin/bash
不加括号会报错,因为是一个整体
[[email protected] ~]# sed -r ‘[email protected]/bin/[email protected]######\\[email protected]‘ /etc/passwd sed: -e expression #1, char 22: invalid reference \\1 on `s‘ command‘s RHS
3)在bash的后面追加
[[email protected] ~]# sed -r ‘[email protected](/bin/bash)[email protected]\\1*******@‘ /etc/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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin saslauth:x:499:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin haldaemon:x:68:68:HAL daemon:/:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin radvd:x:75:75:radvd user:/:/sbin/nologin qemu:x:107:107:qemu user:/:/sbin/nologin ident:x:98:98::/:/sbin/nologin
[[email protected] ~]# sed -r ‘[email protected](/bin/bash)[email protected]######\\1*******@‘ /etc/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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin wang:x:1000:1000:wang:/home/wang:######/bin/bash*******
对配置文件进行搜索替换
selinux的配置文件,未修改
[[email protected] ~]# cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
把SELINUX=disabled这对键值对修改为SELINUX=permissive
[[email protected] ~]# sed ‘[email protected][email protected][email protected]‘ /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=permissive # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
担心把注释也替换了,那么就使用脱义字符定位到行首,那么就修改以SELINUX开头的
[[email protected] ~]# sed ‘[email protected]^[email protected][email protected]‘ /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
示例1——取出虚拟机的网络接口信息的第2行IP地址
显示虚拟机的网络接口信息
[[email protected] ~]# ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255 inet6 fe80::b029:2522:876f:5456 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fc:69:f8 txqueuelen 1000 (Ethernet) RX packets 10428 bytes 978015 (955.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5654 bytes 737168 (719.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
法1:
解决思路:
点心.*是任意字符串
sed ‘[email protected]*inet @@‘ 中.*inet表示IP地址前面的内容,包括前面的空白,也就是任意的字符串。
@@表示无内容,也就把上述内容删除了
再一次搜索替代,把IP地址后面的内容进行替换,替换成空,也就是删除。
对上面的操作一个词形容就是掐头去尾,注意要关闭自动打印
打印第2行的内容1遍
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ inet 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
先掐头
再一次搜索替代,把IP地址后面的内容进行替换,替换成空,也就是删除。
因为只有1行,只出现1处,可以加g,也可以不加
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed ‘[email protected]*inet @@g‘ 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255 [[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed ‘[email protected]*inet @@‘ 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
后去尾
去尾的方法和掐头是一样的,掐头是把前面不要的去掉,去尾是把后面不要的去掉
成功提取出了IP地址
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed ‘[email protected]*inet @@‘ | sed ‘[email protected]*@@‘
192.168.137.72
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed ‘[email protected]*inet @@‘ | sed ‘[email protected]* @@‘
192.168.137.72 192.168.137.255
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed ‘[email protected]*inet @@‘ | sed ‘[email protected]*@ @‘
192.168.137.72
法2:
简化上面的步骤
搜索替换,使用正则表达式的后向引用,\\1就是(.*)的内容,也就是IP地址了。
简而言之搜索的出来的内容替换成想要的IP地址
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed -r ‘[email protected]*inet(.*)netmask.* @\\[email protected]‘ 192.168.137.72 192.168.137.255 [[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed -r ‘[email protected]*inet(.*)netmask.*@\\[email protected]‘ 192.168.137.72
[[email protected] ~]# ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.137.73 netmask 255.255.255.0 broadcast 192.168.137.255 inet6 fe80::20c:29ff:fe90:2d58 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:90:2d:58 txqueuelen 1000 (Ethernet) RX packets 47147 bytes 4270150 (4.0 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 37301 bytes 4624878 (4.4 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
注意空格很重要,inet和192.168.137.72之间是有空格的,所以命令里面也要有空格
平时要注意细节
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed -r ‘[email protected]*inet(.*)netmask.*@\\[email protected]‘ 192.168.137.72 [[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed -r ‘[email protected]*inet (.*)netmask.*@\\[email protected]‘ 192.168.137.72 [[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ inet 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
法3:
最简步骤,对ed的选项进行组合
和法2一样,使用后向引用,就是前面使用括号,后面\\1这样会更方便
注意sed的选项是可以组合的
[[email protected] ~]# ifconfig ens33 | sed -n ‘2p‘ | sed -r ‘[email protected]*inet (.*) netmask.*@\\[email protected]‘ 192.168.137.72 [[email protected] ~]# ifconfig ens33 | sed -n -r ‘[email protected]*inet (.*) netmask.*@\\[email protected]‘
#使用一次管道传输就可以 192.168.137.72
不指明第2行一样可以显示,因为只有第2行可以匹配的
[[email protected] ~]# ifconfig ens33 | sed -n -r ‘[email protected]*inet (.*) netmask.*@\\[email protected]‘ 192.168.137.72
[[email protected] ~]# ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255 inet6 fe80::20c:29ff:fefc:69f8 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fc:69:f8 txqueuelen 1000 (Ethernet) RX packets 8980 bytes 724071 (707.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4108 bytes 571189 (557.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [[email protected] ~]# ifconfig ens33 | sed -r ‘[email protected]*inet (.*) netmask.*@\\[email protected]‘ ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 192.168.137.72 inet6 fe80::20c:29ff:fefc:69f8 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fc:69:f8 txqueuelen 1000 (Ethernet) RX packets 8984 bytes 724483 (707.5 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4111 bytes 572131 (558.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[[email protected] ~]# ifconfig ens33 | sed -r ‘[email protected]*inet (.*) netmask.*@\\[email protected]‘ ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 192.168.137.72 inet6 fe80::b029:2522:876f:5456 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fc:69:f8 txqueuelen 1000 (Ethernet) RX packets 11742 bytes 1101659 (1.0 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6340 bytes 813708 (794.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
法4
先取出第2行,也就是除了第2行其他的都删除
在命令前取反
d: 删除模式空间匹配的行,并立即启用下一轮循环
!:模式空间中匹配行取反处理
[[email protected] ~]# ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255 inet6 fe80::20c:29ff:fefc:69f8 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fc:69:f8 txqueuelen 1000 (Ethernet) RX packets 11953 bytes 958598 (936.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5525 bytes 726003 (708.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [[email protected] ~]# ifconfig ens33 | sed -r ‘2d‘ ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::20c:29ff:fefc:69f8 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:fc:69:f8 txqueuelen 1000 (Ethernet) RX packets 11961 bytes 959310 (936.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5530 bytes 727141 (710.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [[email protected] ~]# ifconfig ens33 | sed -r ‘2!d‘ inet 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
把192.168.137.72前面的所有内容替换为空
注意//之间是没有空格的
使用分号就相当于在命令行同时写上多条命令
[[email protected] ~]# ifconfig ens33 | sed -r ‘2!d;s/.*inet //‘ 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
使用分号就相当于在命令行同时写上多条命令
[[email protected] ~]# ls ;echo a access_log anaconda-ks.cfg c shell_scripts _wang.html
[[email protected] ~]# ls;pwd anaconda-ks.cfg ~ /root
把192.168.137.72后面的所有内容替换为空
注意.*//是没有空格的。
使用分号就相当于在命令行同时写上多条命令
成功提取出了IP地址
[[email protected] ~]# ifconfig ens33 | sed -r ‘2!d;s/.*inet //;s/netmask .*//‘ 192.168.137.72
注意下面都是有空格的,空格是很关键的,要实现精准匹配
[[email protected] ~]# ifconfig ens33 | sed -r ‘2!d;s/.*inet //;s/netmask .* //‘ 192.168.137.72 192.168.137.255 [[email protected] ~]# ifconfig ens33 | sed -r ‘2!d;s/.*inet //‘ 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
[[email protected] ~]# ifconfig ens33 | sed -r ‘2!d;s/.*inet //;s/netmask .* //‘ 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
示例2——显示虚拟机使用的光盘的版本号
使用正则表达式的后向引用
注意空格,哪怕是空一格和两格都是有区别的。
显示几格那么在命令里面也要写几格
不自动打印,并且使用正则表达式的后向引用
和示例1的套路是一样的,括号里面是要显示的内容,后面引用的内容就是括号里面的
[[email protected]s72 ~]# cat /etc/centos-release CentOS Linux release 7.5.1804 (Core) [[email protected] ~]# sed -rn ‘[email protected]*release (.*)\\..*@\\[email protected]‘ /etc/centos-release [[email protected] ~]# sed -rn ‘[email protected]*release (.*)\\..*@\\[email protected]‘ /etc/centos-release 7.5
为了避免出现两位数,比如10版本要写+,表示匹配一个或者一个以上的非点
注意-r和-n选项的前后位置没关系
[[email protected] ~]# sed -rn ‘[email protected]*release ([^.]+)\\..*@\\[email protected]‘ /etc/centos-release [[email protected] ~]# sed -rn ‘[email protected]*release ([^.]+)\\..*@\\[email protected]‘ /etc/centos-release 7 [[email protected] ~]# sed -r -n ‘[email protected]*release ([^.]+)\\..*@\\[email protected]‘ /etc/centos-release 7 [[email protected] ~]# sed -n -r ‘[email protected]*release ([^.]+)\\..*@\\[email protected]‘ /etc/centos-release 7
因为是非点了,外面就不需要写上点
下面是最简洁的最终写法,是所有Linux版本通用的,注意把多余的去掉
[[email protected] ~]# cp /etc/centos-release centos-release [[email protected] ~]# vim centos-release [[email protected] ~]# cat centos-release CentOS Linux release 17.5.1804 (Core)
[[email protected] ~]# sed -nr "[email protected]* release([^.]+).*@\\[email protected]" centos-release 17
[[email protected] ~]# sed -nr "[email protected]* release([^.]+).*@\\[email protected]" /etc/centos-release 7 [[email protected] ~]# cat /etc/centos-release CentOS Linux release 7.5.1804 (Core)
测试写法:
[[email protected] ~]# sed -n -r ‘[email protected]*release ([^.]+)\\..*@\\[email protected]‘ /etc/centos-release 7 [[email protected] ~]# sed -n -r ‘[email protected]*release ([^.])\\..*@\\[email protected]‘ /etc/centos-release 7 [[email protected] ~]# sed -n -r ‘[email protected]*release ([^.]).*@\\[email protected]‘ /etc/centos-release 7 [[email protected] ~]# sed -n -r ‘[email protected]*release ([^.]+).*@\\[email protected]‘ /etc/centos-release
#因为是非点了,外面就不需要写上\\. 7
修改版本,把之前的版本7修改成10,非点就是两位数了。
如果不加上+就只会显示一位数
[[email protected] ~]# cat /etc/centos-release CentOS Linux release 10.5.1804 (Core) [[email protected] ~]# sed -n -r ‘[email protected]*release ([^.]).*@\\[email protected]‘ /etc/centos-release 1
这也是为什么要在括号里面加上+
在数据库版本里面,有5版本的,也有10版本的就可以使用到这种版本判断的方法了。
做事要考虑周到
[[email protected] ~]# sed -n -r ‘[email protected]*release ([^.]+).*@\\[email protected]‘ /etc/centos-release 10
示例3——进行版本判断,如果符合版本就执行相关命令
下面是内核版本,涉及到了18启动和内核管理知识
过滤有两种方法
法1:
[[email protected] ~]# grep linux16 /etc/grub2.cfg linux16 /vmlinuz-3.10.0-862.el7.x86_64 root=UUID=5998ead0-b370-4859-9153-ecf4e2b9dd84 ro rhgb quiet LANG=en_US.UTF-8 linux16 /vmlinuz-0-rescue-cb26ac281315402a9928e9a4c3bedfcd root=UUID=5998ead0-b370-4859-9153-ecf4e2b9dd84 ro rhgb quiet
法2:
[[email protected] ~]# cat /etc/grub2.cfg | grep "linux16" linux16 /vmlinuz-3.10.0-862.el7.x86_64 root=UUID=5998ead0-b370-4859-9153-ecf4e2b9dd84 ro rhgb quiet LANG=en_US.UTF-8 linux16 /vmlinuz-0-rescue-cb26ac281315402a9928e9a4c3bedfcd root=UUID=5998ead0-b370-4859-9153-ecf4e2b9dd84 ro rhgb quiet
[[email protected] ~]# cat /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet" GRUB_DISABLE_RECOVERY="true"
按照上面的最简方法先把版本号取出来,并且设置版本号为变量名
()里面的内容就是进行分组
\\1表示括号里面的内容,\\1就相当于sed里面的-a\\,后面可以添加内容。
LINUX=相当于grep LINUX=,作用是过滤出要修改的那行
[[email protected] ~]# sed -rn ‘[email protected](.*LINUX=".*)" @\\1 xxxxxx @p‘ /etc/default/grub [[email protected] ~]# sed -rn ‘[email protected](.*LINUX=".*)"@\\1 xxxxxx @p‘ /etc/default/grub GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx [[email protected] ~]# sed -rn ‘[email protected](.*LINUX=".*)"@\\1 xxxxxx" @p‘ /etc/default/grub GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx"
修改版本了,修改成系统默认的版本7
[[email protected] ~]# sed -nr ‘[email protected]*release([^.]+).*@\\1 @p‘ /etc/centos-release 10 [[email protected] ~]# vim /etc/centos-release [[email protected] ~]# sed -n ‘s/10/7/p‘ /etc/centos-release CentOS Linux release 7.5.1804 (Core) [[email protected] ~]# cat /etc/centos-release CentOS Linux release 10.5.1804 (Core) [[email protected] ~]# sed -i -n ‘s/10/7/p‘ /etc/centos-release [[email protected] ~]# cat /etc/centos-release CentOS Linux release 7.5.1804 (Core)
法1:
写成脚本
[[email protected] ~]# cat /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet" GRUB_DISABLE_RECOVERY="true"
完整脚本
[[email protected] ~]# cat reset.sh #!/bin/bash version=`sed -nr ‘[email protected]*release([^.]+).*@\\1 @p‘ /etc/centos-release` [ $version = 7 ] && sed -rn ‘[email protected](.*LINUX=".*)"@\\1 xxxxxx" @p‘ /etc/default/grub || exit 2
执行结果
[[email protected] ~]# bash reset.sh GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx"
法2:
脚本内容
[[email protected] ~]# cat reset1.sh #!/bin/bash version=`sed -nr ‘[email protected]*release([^.]+).*@\\1 @p‘ /etc/centos-release` if [ $version -eq 7 ];then sed -r ‘[email protected](quiet)@\\1 [email protected]‘ /etc/default/grub else echo "the OS is $version,there is no target file." exit 2 fi
执行结果
[[email protected] ~]# bash reset1.sh GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx" GRUB_DISABLE_RECOVERY="true"
[[email protected] ~]# sed -nr ‘[email protected](quiet)@\\1 [email protected]‘ /etc/default/grub [[email protected] ~]# sed -r ‘[email protected](quiet)@\\1 [email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx" GRUB_DISABLE_RECOVERY="true"
[[email protected] ~]# cat /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet" GRUB_DISABLE_RECOVERY="true"
法3:
s前面加正则表达式过滤出有LINUX的行/LINUX/,模式匹配的单地址
[[email protected] ~]# sed -r ‘/LINUX/[email protected]("$)@ xxxxxx\\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx" GRUB_DISABLE_RECOVERY="true"
xxxxxx\\1是显示的内容,前面要有空格才可以和前面的隔开?
[[email protected] ~]# sed -r ‘/LINUX/[email protected]("$)@xxxxxx\\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quietxxxxxx" GRUB_DISABLE_RECOVERY="true"
锚定到冒号结尾
[[email protected] ~]# sed -r ‘/LINUX/[email protected]("$)@xxxxxx \\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quietxxxxxx " GRUB_DISABLE_RECOVERY="true" [[email protected] ~]# sed -r ‘/LINUX/[email protected]("$) @xxxxxx\\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet" GRUB_DISABLE_RECOVERY="true"
最佳命令
[[email protected] ~]# sed -r ‘/LINUX/[email protected]("$)@ xxxxxx \\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx " GRUB_DISABLE_RECOVERY="true"
以下方法都不能
[[email protected] ~]# sed -r ‘/LINUX/[email protected](‘ ‘$)@ xxxxxx \\[email protected]‘ /etc/default/grub sed: -e expression #1, char 10: unterminated `s‘ command [[email protected] ~]# sed -r ‘/LINUX/[email protected](‘$)@ xxxxxx \\[email protected]‘ /etc/default/grub -bash: syntax error near unexpected token `)‘ [[email protected] ~]# sed -r ‘/LINUX/[email protected](" "$)@ xxxxxx \\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet" GRUB_DISABLE_RECOVERY="true" [[email protected] ~]# sed -r ‘/LINUX/[email protected](" "$)@ xxxxxx \\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet" GRUB_DISABLE_RECOVERY="true" [[email protected] ~]# sed -r ‘/LINUX/[email protected](""$)@ xxxxxx \\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet" GRUB_DISABLE_RECOVERY="true"
法4
[[email protected] ~]# sed -r ‘6s/("$)/ xxxxxx\\1/‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx" GRUB_DISABLE_RECOVERY="true" [[email protected] ~]# sed -r ‘[email protected]("$)@ xxxxxx\\[email protected]‘ /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed ‘s, release .*$,,g‘ /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx" GRUB_DISABLE_RECOVERY="true"
示例4——取目录的基名
利用搜索替代以及正则表达式里的分组取基名和目录名
使用@作为分隔符
目录是/etc/sysconfig/network-scripts/
[[email protected] ~]# ll /etc/sysconfig/network-scripts/ -d drwxr-xr-x. 2 root root 4096 Apr 15 17:18 /etc/sysconfig/network-scripts/
基名也就是文件名
[[email protected] ~]# basename /etc/sysconfig/network-scripts/ network-scripts
目录名
[[email protected] ~]# dirname /etc/sysconfig/network-scripts/ /etc/sysconfig
sed执行结果,使用了后向引用
[[email protected] ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn ‘[email protected]*/(network-scripts).*/@\\[email protected]‘ network-scripts [[email protected] ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn ‘[email protected]*(network-scripts).*@\\[email protected]‘ network-scripts
[[email protected] ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn ‘[email protected]*(/network-scripts/).*@\\[email protected]‘ /network-scripts/
法2:
.+其中.表示任意一个字符,+表示一个或者一个以上的字符,所以(.+)任意一个以上的字符,两者是并的关系。
?表示0或0个以上,/?就表示反斜线/可有可无
\\1引用括号里面的内容
[[email protected] ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn ‘[email protected]*/(.+)/[email protected]\\[email protected]‘ network-scripts/
创建两个分组(.*/)和(.+)/?,使用正则表达式的后向引用
[[email protected] ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ /etc/sysconfig/ [[email protected] ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ network-scripts/
对其他目录进行测试,根目录是行不通的
[[email protected] ~]# echo ‘/‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ [[email protected] ~]# echo ‘/‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘
目录名
[[email protected] ~]# echo ‘/root‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ / [[email protected] ~]# echo ‘/root/.ssh/‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ /root/ [[email protected] ~]# echo ‘/root/.bashrc‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ /root/
基名
[[email protected] ~]# echo ‘/root‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ root [[email protected] ~]# echo ‘/root/.ssh/‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ .ssh/ [[email protected] ~]# echo ‘/root/.bashrc‘ | sed -rn ‘[email protected](.*/)(.+)/[email protected]\\[email protected]‘ .bashrc
以上是关于文本处理工具——sed进阶的主要内容,如果未能解决你的问题,请参考以下文章
Linux命令进阶:grep,sed,awk全家桶(文本处理技术详例)