• 文本处理工具——sed进阶


    一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 0

    法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 0

    注意空格很重要,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 0
    [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 0

    法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
    7

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

    下面是最简洁的最终写法,是所有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 
     17
    [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

    修改版本,把之前的版本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
    1

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

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

    做事要考虑周到

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

    示例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   2

     执行结果

    [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@("$)@ xxxxxx1@'   /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"

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

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


    作者:wang618
    出处:https://www.cnblogs.com/wang618/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    BCP 命令
    模板复习【updating】
    bzoj3716/4251 [PA2014]Muzeum
    bzoj4318 OSU!
    uoj308 【UNR #2】UOJ拯救计划
    bzoj4695 最假女选手
    省队集训 Day7 选点游戏
    hdu5828 Rikka with Sequence
    bzoj2482 [Spoj1557] Can you answer these queries II
    省队集训 Day6 序列
  • 原文地址:https://www.cnblogs.com/wang618/p/11150439.html
Copyright © 2020-2023  润新知