zoukankan      html  css  js  c++  java
  • 文本处理工具——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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    nowcoderD Xieldy And His Password
    Codeforces681D Gifts by the List
    nowcoder80D applese的生日
    Codeforces961E Tufurama
    Codeforces957 Mahmoud and Ehab and yet another xor task
    nowcoder82E 无向图中的最短距离
    nowcoder82B 区间的连续段
    Codeforces903E Swapping Characters
    Codeforces614C Peter and Snow Blower
    Codeforces614D Skills
  • 原文地址:https://www.cnblogs.com/wang618/p/11150439.html
Copyright © 2011-2022 走看看