美文网首页
linux三剑客

linux三剑客

作者: oceanfly | 来源:发表于2022-07-30 08:51 被阅读0次

    所谓三剑客就是linux中三个可以用linux正则表达式的命令

    • grep 过滤
    • sed 取行 替换
    • awk 取列

    环境准备

    # passwd.txt 内容
    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
    

    grep

    格式:grep 选项 正则 文件

    作用:在文件中找到符合正则条件的行

    选项

    • -v 取反
    • -i 不区分大小写
    • -n 显示匹配到的行在源文件中的行号
    • -o 只输出匹配到的内容
    • -E 扩展正则
    • -w 按单词匹配
    • -A -B -C 可以显示匹配行的前后几行 -A3 后三行 -B3 前三行 -C3前后三行
    • -P 可以使用Perl正则语法

    例子

    # 以noLogin结尾的 不区分大小写 可以去掉-i试试
    [root@centos76 data]# grep -i "noLogin$" passwd.txt 
    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
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    # 加上-v试试  变成不以nologin结尾的了
    [root@centos76 data]# grep -iv "noLogin$" passwd.txt 
    root:x:0:0:root:/root:/bin/bash
    
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    
    halt:x:7:0:halt:/sbin:/sbin/halt
    
    # 再加上-n试试  显示了在源文件中的行号
    [root@centos76 data]# grep -ivn "noLogin$" passwd.txt 
    1:root:x:0:0:root:/root:/bin/bash
    2:
    7:sync:x:5:0:sync:/sbin:/bin/sync
    8:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    9:
    10:halt:x:7:0:halt:/sbin:/sbin/halt
    
    

    grep -E 相当于egrep 可以使用linux正则表达式中的扩展正则

    # -o 只显示匹配到的内容 而不是显示整行
    [root@centos76 data]# grep -ino "noLogin$" passwd.txt 
    3:nologin
    4:nologin
    5:nologin
    6:nologin
    11:nologin
    # -w 按单词匹配 所以用nologin可以匹配到 用no不行
    [root@centos76 data]# grep -w "nologin" passwd.txt 
    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
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    [root@centos76 data]# grep -w "no" passwd.txt 
    [root@centos76 data]#
    

    sed

    作用

    流编辑器 可以对文本进行增删改查

    格式

    sed [OPTION]... '取什么 取到后做什么' [input-file]...

    选项

    • -n 取消默认输出
    • -r 扩展正则
    • -i 直接修改文件
    • -e 多次编辑

    sed -n '1,3p' passwd.txt 取1到3行并打印

    # 准备实验对象passwd.txt
    [root@centos76 data]# cat /etc/passwd > passwd.txt
    [root@centos76 data]# sed -n '1,3p' passwd.txt 
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    

    -n选项取消默认打印,去掉后会发现1到3行打印了两遍,其他行也都打印了,自己试试体会下。
    '1,3p' 这个就是格式中的脚本部分,作用是:取什么 取到后做什么
    1,3表示取1到3行 p表示取到后打印
    改成'4p'自己试下。

    sed -n '/root/p' passwd.txt 取到包含root的行并打印

    [root@centos76 data]# sed  -n '/root/p' passwd.txt 
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    

    //之间的内容 世界是正则表达式

    sed "1,10d" passwd.txt 删除1到10行并打印剩下的行

    [root@centos76 data]# sed  "1,10d" passwd.txt 
    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
    chrony:x:998:996::/var/lib/chrony:/sbin/nologin
    nginx:x:997:995:nginx user:/var/cache/nginx:/sbin/nologin
    ocean:x:1000:1000::/home/ocean:/bin/bash
    

    执行上面这些删除命令后,你会发现passwd.txt源文件并没有发生变化,如果想修改源文件,需要加-i参数,-i.bak会先备份后修改源文件,建议修改前备份

    sed -i.bak "1,10d" passwd.txt 备份后在源文件中删除1到10行,真实删除

    [root@centos76 data]# sed -i.bak  "1,10d" passwd.txt
    [root@centos76 data]# wc passwd.txt
     11  20 560 passwd.txt
    [root@centos76 data]# wc passwd.txt.bak 
     21  30 945 passwd.txt.bak
    

    建议:操作前备份,操作后检查

    sed "s/nologin/NOLOGIN/g" passwd.txt 把nologin替换成NOLOGIN

    s/查找的内容/替换的内容/g s表示替换 g表示全局,///可以替换成###,@@@,只要可以分割即可//之间实际上是正则表达式

    [root@centos76 data]# sed "s/nologin/NOLOGIN/g" passwd.txt
    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
    chrony:x:998:996::/var/lib/chrony:/sbin/NOLOGIN
    nginx:x:997:995:nginx user:/var/cache/nginx:/sbin/NOLOGIN
    ocean:x:1000:1000::/home/ocean:/bin/bash
    

    sed '2a hello' passwd.txt 第二行之后添加一行hello是第三行
    sed '2i hello' passwd.txt 第二行之前插入一行hello是第二行

    sed 获取ip地址

    sed默认不支持扩展正则 加上-r支持扩展正则
    s#A#B#g 用来把A替换成B

    # ipv4
    > A=`^.*inet (([0-9]{1,3}\.){3}[0-9]{1,3}).*$`
    > B=`\1` 分组引用,引用`([0-9]{1,3}\.){3}[0-9]{1,3}`
    [root@centos76 ~]# ip address show ens33|grep "inet "|sed -r 's#^.*inet (([0-9]{1,3}\.){3}[0-9]{1,3}).*$#\1#g'
    192.168.100.100
    # ipv6
    > A=`^.*inet6 (([0-9a-fA-F]{,4}:){5}[0-9a-fA-F]{,4}).*$`
    > B=`\1` 分组引用,引用`([0-9a-fA-F]{,4}:){5}[0-9a-fA-F]{,4}`
    [root@centos76 ~]# ip address show ens33|grep "inet6"|sed -r 's#^.*inet6 (([0-9a-fA-F]{,4}:){5}[0-9a-fA-F]{,4}).*$#\1#g'
    fe80::6ac3:3104:7003:e3fe
    

    小结

    • sed -n {1,4p} 文件名 按行查找-取什么:1-4行,取到后做什么:p打印。
    • sed -n '/A/p' 文件名 按正则查找-取什么 :能匹配正则A的行,取到后做什么:p打印。
    • sed "s/A/B/g" 文件名 替换-把正则A匹配的内容替换成B,A中可以分组,B中可以引用。

    awk

    作用

    用-F指定的分割符将文件分割,分割后
    0代表整行1代表第一列
    2代表第二列NF代表最后一列
    $(NF-1)代表倒数第二列
    NF 列数
    NR 行号
    然后执行program指定的程序

    格式

    awk [options] -f progfile [--] file ...
    awk [options] [--] 'program' file ... 下面讲的都是这个格式
    'program'的格式是 '条件{动作}'

    选项

    • -F 指定分割符

    awk '/games/' passwd.txt

    只有条件没有动作 表示过滤符合条件的行
    条件可以是正则 /正则/ awk默认支持扩展正则
    也可以是范围NR==1,NR==3 ,分割表示1到3行
    也可以是多个条件 NR>=1 && NR<=3

    [root@centos76 data]# awk '/games/' passwd.txt 
    games:x:12:100:games:/usr/games:/sbin/nologin
    [root@centos76 data]# awk 'NR==1,NR==3' passwd.txt 
    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
    

    awk -F':' '{print $1}' passwd.txt

    只有动作没有条件 表示所有的行都要执行该program
    这里指定了分割符为:,用分隔符把passwd.txt中的每一行分割成多个列
    之后执行'{print $1}'这段程序
    就是打印第一列的内容

    [root@centos76 data]# awk -F':' '{print $1}' passwd.txt
    games
    ftp
    nobody
    systemd-network
    dbus
    polkitd
    sshd
    postfix
    chrony
    nginx
    ocean
    # 这里中间可以加上-- 
    # --的作用是 明确--前面的部分是awk [options]
    # 明确--后面的部分是'program' file ...
    [root@centos76 data]# awk -F ':' -- '{print $1}' passwd.txt
    games
    ftp
    nobody
    systemd-network
    dbus
    polkitd
    sshd
    postfix
    chrony
    nginx
    ocean
    

    awk -F ':' 'NR==1,NR==3{print $1}' passwd.txt

    既有条件又有动作 表示只对符合条件的行执行对应的动作

    [root@centos76 data]# awk -F ':' 'NR==1,NR==3{print $1}' passwd.txt 
    games
    ftp
    nobody
    

    例子

    sed专业取行

    用sed将/etc/passwd文件中第一行到最后一行重定向到passwd.txt

    # -n 和 p 配对 -n默认不打印 p打印  结果就是只打印符合条件的
    sed -n '1,$p' /etc/passwd > passwd.txt
    

    显示/etc/passwd的第三行到第七行

    sed -n '3,7p' /etc/passwd
    # 表示单个条件
    awk 'NR>=3 && NR<=7' /etc/passwd
    # , 表示范围 从第三行到第7行
    awk 'NR==3,NR==7' /etc/passwd
    

    awk专业取列

    用sed取出passwd.txt中用户名为dbus的行中备注列

    dbus:x:81:81:System message bus:/:/sbin/nologin #取出System message bus
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin     #取出FTP User
    
    # -r 用来使用增强正则  n和p配对 g
    # s#找什么#替换成什么#g 
    sed -rn 's#([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*)#\5#gp' passwd.txt
    [root@centos76 sjk]# sed -rn 's#dbus:([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*)#\4#p' passwd.txt
    System message bus
    [root@centos76 sjk]# sed -rn 's#ftp:([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*)#\4#p' passwd.txt
    FTP User
    [root@centos76 sjk]# awk -F: '$1=="dbus"{print $5}' passwd.txt 
    System message bus
    [root@centos76 sjk]# awk -F: '$1=="ftp"{print $5}' passwd.txt 
    FTP User
    

    使用awk取passwd.txt用户名及家目录并显示行号

    [root@centos76 sjk]# awk -F: '{print NR,$1,$6}' passwd.txt |column -t
    1   root             /root
    2   bin              /bin
    3   daemon           /sbin
    4   adm              /var/adm
    

    passwd.txt中uid>10时 显示整行

    [root@centos76 sjk]# awk -F: '$3>10{print NR,$0}' passwd.txt
    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
    [root@centos76 data]# awk -F: '$1~/games/{print NR,$0}' passwd.txt
    1 games:x:12:100:games:/usr/games:/sbin/nologin
    

    相关文章

      网友评论

          本文标题:linux三剑客

          本文链接:https://www.haomeiwen.com/subject/ryhkwrtx.html