一sed的搜索替代

(一)常见的和替代相关的选项

搜索替代,和vim的写法很像

s///:查找替换,支持使用其它分隔符,s@@@,s###

p: 显示替换成功的行,就是打印。

w /PATH/TO/SOMEFILE :将替换成功的行保存至文件中

替换标记:

g: 行内全局替换和博客园里面的替换全部是一样的效果

注意搜索最好不要使用斜线/,因为linux系统里面有很多斜线,比如目录或者文件路径。

前面搜索的是模式,使用正则表达式$,后面替换的内容就不要了。

(1)s///:查找替换,支持使用其它分隔符,s@@@,s###

把/bin/bash结尾的行替换为/sbin/nologin结尾

[root@centos72 ~]# sed  's@/bin/bash$@/sbin/nologin@'    /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里面也是一样,有测试和真正执行。

[root@centos72 ~]# 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

[root@centos72 ~]# sed    -r    's@(/bin/bash)$@######@'    /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的前面追加了###

文件未修改内容

[root@centos72 ~]# 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行修改,忽略了命令

[root@centos72 ~]# sed    -r    's@(/bin/bash)$@######\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

不加括号会报错,因为是一个整体

[root@centos72 ~]# sed    -r    's@/bin/bash$@######\1@'    /etc/passwd
sed: -e expression #1, char 22: invalid reference \1 on `s' command's RHS

3)在bash的后面追加

[root@centos65 ~]#  sed    -r    's@(/bin/bash)$@\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
[root@centos72 ~]# sed    -r    's@(/bin/bash)$@######\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的配置文件,未修改

[root@centos72 ~]# 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

[root@centos72 ~]# sed  's@SELINUX=disabled@SELINUX=permissive@'    /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开头的

[root@centos72 ~]# sed  's@^SELINUX=permissive@SELINUX=disabled@'    /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地址

显示虚拟机的网络接口信息

[root@centos72 ~]# 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

法1:

解决思路:

点心.*是任意字符串

sed 's@.*inet @@'  中.*inet表示IP地址前面的内容,包括前面的空白,也就是任意的字符串。

@@表示无内容,也就把上述内容删除了

再一次搜索替代,把IP地址后面的内容进行替换,替换成空,也就是删除。

对上面的操作一个词形容就是掐头去尾,注意要关闭自动打印

打印第2行的内容1遍

[root@centos72 ~]#  ifconfig    ens33   |   sed   -n   '2p'
inet 192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255

先掐头

再一次搜索替代,把IP地址后面的内容进行替换,替换成空,也就是删除。

因为只有1行,只出现1处,可以加g,也可以不加

[root@centos72 ~]#  ifconfig    ens33   |   sed   -n   '2p'  |   sed   's@.*inet @@g'
192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255
[root@centos72 ~]# ifconfig ens33 | sed -n '2p' | sed 's@.*inet @@'
192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255

后去尾

去尾的方法和掐头是一样的,掐头是把前面不要的去掉,去尾是把后面不要的去掉

成功提取出了IP地址


[root@centos72 ~]#  ifconfig    ens33   |   sed   -n   '2p'  |   sed   's@.*inet @@'   |   sed  's@net.*@@'
192.168.137.72
[root@centos72 ~]# ifconfig ens33 | sed -n '2p' | sed 's@.*inet @@' | sed 's@net.* @@'
192.168.137.72 192.168.137.255
[root@centos72 ~]# ifconfig ens33 | sed -n '2p' | sed 's@.*inet @@' | sed 's@net.*@ @'
192.168.137.72

法2:

简化上面的步骤

搜索替换,使用正则表达式的后向引用,\1就是(.*)的内容,也就是IP地址了。

简而言之搜索的出来的内容替换成想要的IP地址

[root@centos72 ~]#  ifconfig    ens33   |   sed   -n   '2p'  |   sed   -r   's@.*inet(.*)netmask.* @\1@'
192.168.137.72 192.168.137.255
[root@centos72 ~]# ifconfig ens33 | sed -n '2p' | sed -r 's@.*inet(.*)netmask.*@\1@'
192.168.137.72
[root@centos73 ~]# 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

注意空格很重要,inet和192.168.137.72之间是有空格的,所以命令里面也要有空格

平时要注意细节

[root@centos72 ~]#  ifconfig    ens33   |   sed   -n   '2p'  |   sed   -r   's@.*inet(.*)netmask.*@\1@'
192.168.137.72
[root@centos72 ~]# ifconfig ens33 | sed -n '2p' | sed -r 's@.*inet (.*)netmask.*@\1@'
192.168.137.72
[root@centos72 ~]# 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的选项是可以组合的

[root@centos72 ~]#  ifconfig    ens33   |   sed   -n   '2p'  |   sed   -r   's@.*inet (.*) netmask.*@\1@'
192.168.137.72
[root@centos72 ~]# ifconfig ens33 | sed -n -r '2s@.*inet (.*) netmask.*@\1@p'
#使用一次管道传输就可以
192.168.137.72

不指明第2行一样可以显示,因为只有第2行可以匹配的

[root@centos72 ~]# ifconfig    ens33   |     sed  -n   -r   's@.*inet (.*) netmask.*@\1@p'
192.168.137.72
[root@centos72 ~]# 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 [root@centos72 ~]# ifconfig ens33 | sed -r '2s@.*inet (.*) netmask.*@\1@'
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
[root@centos72 ~]#  ifconfig    ens33   |     sed     -r   's@.*inet (.*) netmask.*@\1@'
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

法4

先取出第2行,也就是除了第2行其他的都删除

在命令前取反

d: 删除模式空间匹配的行,并立即启用下一轮循环

!:模式空间中匹配行取反处理

[root@centos72 ~]# 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 [root@centos72 ~]# 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 [root@centos72 ~]# 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前面的所有内容替换为空

注意//之间是没有空格的

使用分号就相当于在命令行同时写上多条命令

[root@centos72 ~]# ifconfig   ens33   |   sed   -r    '2!d;s/.*inet //'
192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255

使用分号就相当于在命令行同时写上多条命令

[root@centos72 ~]# ls  ;echo
a access_log anaconda-ks.cfg c shell_scripts _wang.html
[root@centos72 ~]# ls;pwd
anaconda-ks.cfg ~
/root

把192.168.137.72后面的所有内容替换为空

注意.*//是没有空格的。

使用分号就相当于在命令行同时写上多条命令

成功提取出了IP地址

[root@centos72 ~]# ifconfig   ens33   |   sed   -r    '2!d;s/.*inet //;s/netmask .*//'
192.168.137.72

注意下面都是有空格的,空格是很关键的,要实现精准匹配

[root@centos72 ~]# ifconfig   ens33   |   sed   -r    '2!d;s/.*inet //;s/netmask .* //'
192.168.137.72 192.168.137.255
[root@centos72 ~]# ifconfig ens33 | sed -r '2!d;s/.*inet //'
192.168.137.72 netmask 255.255.255.0 broadcast 192.168.137.255

[root@centos72 ~]# 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的套路是一样的,括号里面是要显示的内容,后面引用的内容就是括号里面的

[root@centos72 ~]# cat /etc/centos-release
CentOS Linux release 7.5.1804 (Core)
[root@centos72 ~]# sed -rn 's@.*release (.*)\..*@\1@p' /etc/centos-release
[root@centos72 ~]# sed -rn 's@.*release (.*)\..*@\1@p' /etc/centos-release
7.5

为了避免出现两位数,比如10版本要写+,表示匹配一个或者一个以上的非点

注意-r和-n选项的前后位置没关系

[root@centos72 ~]# sed  -rn    's@.*release  ([^.]+)\..*@\1@p'     /etc/centos-release
[root@centos72 ~]# sed -rn 's@.*release ([^.]+)\..*@\1@p' /etc/centos-release
7
[root@centos72 ~]# sed -r -n 's@.*release ([^.]+)\..*@\1@p' /etc/centos-release
7
[root@centos72 ~]# sed -n -r 's@.*release ([^.]+)\..*@\1@p' /etc/centos-release

因为是非点了,外面就不需要写上点

下面是最简洁的最终写法,是所有Linux版本通用的,注意把多余的去掉

[root@centos72 ~]# cp  /etc/centos-release   centos-release
[root@centos72 ~]# vim centos-release
[root@centos72 ~]# cat centos-release
CentOS Linux release 17.5.1804 (Core)
[root@centos72 ~]# sed -nr  "s@.* release([^.]+).*@\1@p"  centos-release
 
[root@centos72 ~]# sed -nr  "s@.* release([^.]+).*@\1@p"  /etc/centos-release
7
[root@centos72 ~]# cat /etc/centos-release
CentOS Linux release 7.5.1804 (Core)

测试写法:

[root@centos72 ~]# sed  -n  -r   's@.*release ([^.]+)\..*@\1@p'     /etc/centos-release
7
[root@centos72 ~]# sed -n -r 's@.*release ([^.])\..*@\1@p' /etc/centos-release
7
[root@centos72 ~]# sed -n -r 's@.*release ([^.]).*@\1@p' /etc/centos-release
7
[root@centos72 ~]# sed -n -r 's@.*release ([^.]+).*@\1@p' /etc/centos-release
#因为是非点了,外面就不需要写上\.

修改版本,把之前的版本7修改成10,非点就是两位数了。

如果不加上+就只会显示一位数

[root@centos72 ~]# cat  /etc/centos-release
CentOS Linux release 10.5.1804 (Core)
[root@centos72 ~]# sed -n -r 's@.*release ([^.]).*@\1@p' /etc/centos-release

这也是为什么要在括号里面加上+

在数据库版本里面,有5版本的,也有10版本的就可以使用到这种版本判断的方法了。

做事要考虑周到

[root@centos72 ~]# sed  -n  -r   's@.*release ([^.]+).*@\1@p'     /etc/centos-release

示例3——进行版本判断,如果符合版本就执行相关命令

下面是内核版本,涉及到了18启动和内核管理知识

过滤有两种方法

法1:

[root@centos72 ~]# 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:

[root@centos72 ~]# 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
[root@centos72 ~]# 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=,作用是过滤出要修改的那行

[root@centos72 ~]# sed   -rn      's@(.*LINUX=".*)" @\1 xxxxxx @p'         /etc/default/grub
[root@centos72 ~]# sed -rn 's@(.*LINUX=".*)"@\1 xxxxxx @p' /etc/default/grub
GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx
[root@centos72 ~]# sed -rn 's@(.*LINUX=".*)"@\1 xxxxxx" @p' /etc/default/grub
GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx"

修改版本了,修改成系统默认的版本7

[root@centos72 ~]# sed  -nr   's@.*release([^.]+).*@\1 @p'    /etc/centos-release
10
[root@centos72 ~]# vim /etc/centos-release
[root@centos72 ~]# sed -n 's/10/7/p' /etc/centos-release
CentOS Linux release 7.5.1804 (Core)
[root@centos72 ~]# cat /etc/centos-release
CentOS Linux release 10.5.1804 (Core)
[root@centos72 ~]# sed -i -n 's/10/7/p' /etc/centos-release
[root@centos72 ~]# cat /etc/centos-release
CentOS Linux release 7.5.1804 (Core)

法1:

写成脚本

[root@centos72 ~]#  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"

完整脚本

[root@centos72 ~]# cat  reset.sh
#!/bin/bash
version=`sed -nr 's@.*release([^.]+).*@\1 @p' /etc/centos-release`
[ $version = 7 ] && sed -rn 's@(.*LINUX=".*)"@\1 xxxxxx" @p' /etc/default/grub || exit

执行结果

[root@centos72 ~]# bash  reset.sh
GRUB_CMDLINE_LINUX="rhgb quiet xxxxxx"

法2:

脚本内容

[root@centos72 ~]# cat  reset1.sh
#!/bin/bash
version=`sed -nr 's@.*release([^.]+).*@\1 @p' /etc/centos-release`
if [ ${version} -eq 7 ];then sed -r 's@(quiet)@\1 xxxxxx@' /etc/default/grub
else
echo "the OS is $version,there is no target file."
exit 2
fi

执行结果

[root@centos72 ~]# 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"
[root@centos72 ~]# sed   -nr   's@(quiet)@\1 xxxxxx@'   /etc/default/grub
[root@centos72 ~]# sed -r 's@(quiet)@\1 xxxxxx@' /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"
[root@centos72 ~]# 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/,模式匹配的单地址

[root@centos72 ~]# sed  -r  '/LINUX/s@("$)@ 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"

xxxxxx\1是显示的内容,前面要有空格才可以和前面的隔开?

[root@centos72 ~]# sed  -r  '/LINUX/s@("$)@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 quietxxxxxx"
GRUB_DISABLE_RECOVERY="true"

锚定到冒号结尾

[root@centos72 ~]# sed  -r  '/LINUX/s@("$)@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 quietxxxxxx "
GRUB_DISABLE_RECOVERY="true"
[root@centos72 ~]# sed -r '/LINUX/s@("$) @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"
GRUB_DISABLE_RECOVERY="true"

最佳命令

[root@centos72 ~]#  sed  -r  '/LINUX/s@("$)@   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"

以下方法都不能

[root@centos72 ~]#  sed  -r  '/LINUX/s@(' '$)@   xxxxxx \1@'   /etc/default/grub
sed: -e expression #1, char 10: unterminated `s' command
[root@centos72 ~]# sed -r '/LINUX/s@('$)@ xxxxxx \1@' /etc/default/grub
-bash: syntax error near unexpected token `)'
[root@centos72 ~]# sed -r '/LINUX/s@(" "$)@ 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"
GRUB_DISABLE_RECOVERY="true"
[root@centos72 ~]# sed -r '/LINUX/s@(" "$)@ 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"
GRUB_DISABLE_RECOVERY="true"
[root@centos72 ~]# sed -r '/LINUX/s@(""$)@ 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"
GRUB_DISABLE_RECOVERY="true"

法4

[root@centos72 ~]# 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"
[root@centos72 ~]# 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"

示例4——取目录的基名

利用搜索替代以及正则表达式里的分组取基名和目录名

使用@作为分隔符

目录是/etc/sysconfig/network-scripts/

[root@centos72 ~]# ll  /etc/sysconfig/network-scripts/  -d
drwxr-xr-x. 2 root root 4096 Apr 15 17:18 /etc/sysconfig/network-scripts/

基名也就是文件名

[root@centos72 ~]# basename   /etc/sysconfig/network-scripts/
network-scripts

目录名

[root@centos72 ~]# dirname   /etc/sysconfig/network-scripts/
/etc/sysconfig

sed执行结果,使用了后向引用

[root@centos72 ~]# echo   "/etc/sysconfig/network-scripts/"   |   sed   -rn    's@.*/(network-scripts).*/@\1@p'
network-scripts
[root@centos72 ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn 's@.*(network-scripts).*@\1@p'
network-scripts
[root@centos72 ~]# echo   "/etc/sysconfig/network-scripts/"   |   sed   -rn    's@.*(/network-scripts/).*@\1@p'
/network-scripts/

法2:

.+其中.表示任意一个字符,+表示一个或者一个以上的字符,所以(.+)任意一个以上的字符,两者是并的关系。

?表示0或0个以上,/?就表示反斜线/可有可无

\1引用括号里面的内容

[root@centos72 ~]# echo   "/etc/sysconfig/network-scripts/"   |   sed   -rn    's@.*/(.+)/?@\1@p'
network-scripts/

创建两个分组(.*/)和(.+)/?,使用正则表达式的后向引用

[root@centos72 ~]#  echo   "/etc/sysconfig/network-scripts/"   |   sed   -rn    's@(.*/)(.+)/?@\1@p'
/etc/sysconfig/
[root@centos72 ~]# echo "/etc/sysconfig/network-scripts/" | sed -rn 's@(.*/)(.+)/?@\2@p'
network-scripts/

对其他目录进行测试,根目录是行不通的

[root@centos72 ~]# echo   '/'     |   sed   -rn    's@(.*/)(.+)/?@\1@p'
[root@centos72 ~]# echo '/' | sed -rn 's@(.*/)(.+)/?@\2@p'

目录名

[root@centos72 ~]# echo   '/root'     |   sed   -rn    's@(.*/)(.+)/?@\1@p'
/
[root@centos72 ~]# echo '/root/.ssh/' | sed -rn 's@(.*/)(.+)/?@\1@p'
/root/
[root@centos72 ~]# echo '/root/.bashrc' | sed -rn 's@(.*/)(.+)/?@\1@p'
/root/

基名

[root@centos72 ~]# echo   '/root'     |   sed   -rn    's@(.*/)(.+)/?@\2@p'
root
[root@centos72 ~]# echo '/root/.ssh/' | sed -rn 's@(.*/)(.+)/?@\2@p'
.ssh/
[root@centos72 ~]# echo '/root/.bashrc' | sed -rn 's@(.*/)(.+)/?@\2@p'
.bashrc

文本处理工具——sed进阶的更多相关文章

  1. Shell 编程 文本处理工具 sed

    本篇主要写一些shell脚本文本处理工具sed的使用. 概述 sed(Stream EDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除.替换.添加 ...

  2. 文本处理工具sed

    处理文本的工具sed  行编辑器 ,默认自带循环. sed是一种流编辑器,它一次处理一行内容. 功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等 sed工具 用法: sed ...

  3. Linux文本处理工具——Sed

    sed:数据流编辑器: awk:报告文本的生成器 sed 基本用法:(Stream EDitor) Stream 流 EDitor 编辑器 行编辑器 全屏编辑器:vi/vimsed:内存空间(模式空间 ...

  4. 文本处理工具——sed基础

    一sed介绍 三剑客是grep,sed,awk,功能都很强大. 其中sed是Stream EDitor,流编辑器 行,编辑器的简写,它一次处理一行内容. sed的强大在于可以对文件进行修改,很适合在脚 ...

  5. Pyp 替代sed,awk的文本处理工具

    Linux上文本处理工具虽不少,像cut,tr,join,split,paste,sort,uniq,sed,awk这些经典工具让人眼花缭乱,而且都太老了,使用方法都不太人性化,尤其awk,语法简直反 ...

  6. 三大文本处理工具grep、sed及awk的简单介绍

    grep.sed和awk都是文本处理工具,虽然都是文本处理工具单却都有各自的优缺点,一种文本处理命令是不能被另一个完全替换的,否则也不会出现三个文本处理命令了.只不过,相比较而言,sed和awk功能更 ...

  7. 轻松学会文本处理工具之二 linux sed命令

    sed命令的语法格式: sed的命令格式: sed [option]  'sed command'filename sed的脚本格式:sed [option] -f  'sed  script'fil ...

  8. 【Linux】 字符串和文本处理工具 grep & sed & awk

    Linux字符串&文本处理工具 因为用linux的时候主要用到的还是字符交互界面,所以对字符串的处理变得十分重要.这篇介绍三个常用的字符串处理工具,包括grep,sed和awk ■ grep ...

  9. Linux的文本处理工具浅谈-awk sed grep

    Linux的文本处理工具浅谈 awk   老大 [功能说明] 用于文本处理的语言(取行,过滤),支持正则 NR代表行数,$n取某一列,$NF最后一列 NR==20,NR==30 从20行到30行 FS ...

随机推荐

  1. Angular JS - 9 - SeaJS加载js模块

    seajs加载模块的三种方式 1.seajs.use() 加载入口模块,类似于Java的main函数 2.require:      当在一个模块中需要用到其它模块时一般用require加载 1)   ...

  2. UITableViewCell的移动

    看到Metro大都会 这个App中扣款顺序有个cell可以移动,于是觉得是时候回忆一下UITableView的基本使用了.其实他这个移动cell的功能是系统自带的. 代码主要是这样: // // Vi ...

  3. Git 中关于一次完整的提交的命令

    1.创建仓库(git init .git clone URL) 有两种新建 Git 项目仓库的方法.第一种是在本地通过初始化来创建新的 Git 仓库.第二种是从已有的 Git 远程仓库中克隆出一个仓库 ...

  4. Bugku | 游戏过关

    思路:绕过判断,直接跳转到算flag的函数哪里 1.找到计算flag的函数在哪里,记住 "0075e940",这是入口 2.找到一个现成的跳转指令,修改它: 3.重新运行一遍,得到 ...

  5. 116、TensorFlow变量的版本

    import tensorflow as tf v = tf.get_variable("v", shape=(), initializer=tf.zeros_initialize ...

  6. iview+vue 使用中遇到的问题(表格、select、radio)

    1.iview+vue中,对表头的动态设置: iview表头若是需要动态设置,可以有两个方法,第一种: children: [ { title: '2017年', align: 'center', k ...

  7. .net 运行原理

    刚学习那会,感觉.net运行原理是很复杂的,也去了解过相关的东西,但是很晦涩,难于理解.感觉有些难了,也就放弃了解了.今天回头想想,也是当时有些毛躁了,不管怎么说,时至今日是有些明白运行原理. 从头开 ...

  8. laravel artisan工具的使用

    Artisan是laravel中自带的命令行工具的名称(一个php文件,放在laravel框架的根目录,因此命令的使用都是在根目录下的). 它提供了一些对应用开发帮助的命令,可以使用list命令列出所 ...

  9. Html5 学习笔记 【PC固定布局】 实战2 导航栏搜索区域

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...

  10. vue (UI)