Shell中的文本处理三剑客grep、sed、awk(全网最全,没有之一)

    技术2025-03-06  27

     

    目录

    grep命令

    sed命令

    awk命令

    课后练习


    grep命令

    1.grep的格式

    grep root passwad 在passwd中过滤root grep ^root passwd 过滤以root开头的信息 grep root$ passwd 过滤以root结尾的信息 grep -i root passwd 忽略大小写 grep -E "\<root" passwd root字符之前不能有字符 grep -E "root\>" passwd  root字符之后不能有字符 grep -3 lebron passwd 显示关键字与其前后三行 grep -n lebron passwd  显示匹配行所在行号 grep -A3 lebron passwd  显示匹配行以及下面3行 grep -B3 lebron passwd 显示匹配行以及上面3行 grep -v 反向过滤

     

    grep root passwd            在passwd中过滤root

    grep -i root passwd         在passwd中过滤root(忽略大小写)

     

    grep -i ^root passwd                         在passwd中过滤以root开头的行(忽略大小写)

    grep -i root$ passwd                         在passwd中过滤以root结尾的行(忽略大小写)

    grep -iE "^root|root$" passwd         以root开头或以root结尾的

    grep -iE "^root|root$" passwd -v     除去以root开头或以root结尾的

     

    grep -iE "\<root" passwd        root前不能有字符

    grep -iE "root\>" passwd        root后不能有字符

    grep -iE "\<root\>" passwd     root前后都不能有字符 

     

    grep -2 ROOT passwd          显示关键字所在行及其前后两行

    grep -B2 ROOT passwd        显示关键字所在行及其之前两行

    grep -A2 ROOT passwd        显示关键字所在行及其之后两行

    grep -n ROOT passwd           显示关键字所在行及其行号

     

     

    2.grep字符数量匹配规则

    w...s w开头,s结尾中间任意3个字符 ....s s结尾前面任意4个字符 "ws*" w、s出现任意次 "ws?" w、s出现0-1次 "ws+" w、s出现1-任意次 "ws{5}" 出现5次 "ws{3,5}" 出现3-5次 "ws{,5}" 出现0-5次 "ws{0,5}" 出现0-5次 "ws{2,}" 出现2-任意次 "(ws){2}" “ws”这个字符作为整体出现2次

     

    grep -E "w...s" westos 

    grep -E "..s" westos

    grep -E "w.." westos 

     

    grep -E "ws*" westos

    grep -E "ws?" westos

    grep -E "ws+" westos   

     

    grep -E "ws{4}" westos

    grep -E "ws{2,4}" westos 

    grep -E "ws{,4}" westos

    grep -E "ws{3,}" westos 

     

    grep -E "(gb){2}" westos             gb作为整体出现两次

    grep -E "(gb){,2}" westos            gb作为整体出现至多两次

    grep -E "w(gb){1,2}s" westos     在w与s之间gb作为整体出现至多两次

     

     

    sed命令

    p 打印(需加 -n) d 删除 a 追加 i 插入 c 更改/替换 w 写入 r 整合文件 's/xx/xx/g' 字符替换

     

    1.  p   打印

    sed -n '3p' westos            显示westos的第三行内容

    sed -n '3,7p' westos         显示westos的3到7行内容

    sed -n '3p;7p' westos       显示westos的第3和第7行内容

    sed -n '$p' westos             显示westos的尾行内容

     

    sed -n '/^daddy/p' passwd     显示以daddy开头的行

    sed -n '/bash$/p' passwd        显示以bash结尾的行

     

    2.  d   删除

    sed '1,2d' westos         删除westos中的1、2行并显示

    sed '1d;4d' westos       删除westos中的1、4行并显示

    sed '/^p/d' westos        删除westos中以p开头的行并显示

    sed '/g$/d' westos         删除westos中以g结尾的行并显示

    sed '/g$/!d' westos        删除westos中以g结尾之外的行并显示(上一步的反向操作)

     

    3.  a   追加

    sed 'aoligay' westos               在westos的每行后面追加oligay

    sed '$aoligay' westos             在westos的尾行后面追加oligay

    sed '1aoligay' westos             在westos的首行后面追加oligay

     

    sed '/gg/aoligay' westos                  /gg/指在此行后追加

    sed '/pig/aoligay\nbro' westos        \n为换行符

     

    4.  i   插入

    i与a的不同在于,a在指定行后追加,i在指定行前插入

    sed '3i hhhhhh' westos                 在westos第三行前插入hhhhh

    sed '$i hhhhhh' westos                 在westos尾行前插入hhhhh

    sed '/pig/i hhhhhh' westos            在westos中的/pig/行前插入hhhhh

    sed '/pig/i hhhhhh\ngg' westos    在westos中的/pig/行前插入hhhhh gg

     

    5.  c  更改

    sed '$c dsb' passwd                   将最后一行替换为dsb

    sed '/bash$/c dsb' passwd        将以bash结尾的行替换为dsb

    sed '/^lbj/c dsb' passwd            将以lbj开头的行替换为dsb

     

    6.  w  写

    sed '/hey/w file' westos  

    7.  r   整合

    sed '2r file' westos     将file文件的内容合并至westos的第二行后

    sed '$r file' westos     将file文件的内容合并至westos的尾行后

     

    8.  替换

    sed '1,3s/bash/dunk/' passwd                      将passwd中1、3行的bash替换为dunk

    sed 's/lbj/kobe/g;s/bash/gkd/g' passwd      将passwd中所有lbj替换为kobe;所有bash替换为gkd

    sed '/westos/,/zxn/s/bash/hhh/g' passwd    将passwd中westos与zxn之间的bash替换为hhh

     

    sed 's/\//@/g' passwd                将passwd中所有的/替换为@

    sed 's@\/@:@g' passwd           与上命令效果相同,只是将分割符换为@

     

     

    awk命令

    格式: awk  -F  分隔符  BEGIN{}{}END{}  filename NR 行数 NF 每行的列数 FILENAME 文件名称本身 “westos” 字符串 $1 指定列数

     

    awk -F : '{print NR}' passwd       显示文件的所有行数

    awk -F : '{print NF}' passwd       显示文件每行的列数

    awk -F : '{print $1}' passwd        显示文件第一列的内容

     

    awk -F : '{print FILENAME}' passwd        显示文件名称(原文件有几行就显示几次)

    awk -F : '{print "ohou"}' passwd              显示输入的字符串(原文件有几行就显示几次)

     

     

    /bash$/ 条件:以bash结尾 /条件1/ | | /条件2/ 条件1或条件2 /条件1/ && /条件2/ 条件1、2同时成立

    awk -F : 'BEGIN{print "name"}/bash$/{print $1}END{print "over"}' passwd

    awk -F : 'BEGIN{print "name"}/bash$/||/nologin$/{print $1}END{print "over"}' passwd

    awk -F : 'BEGIN{print "name"}/bash$/||/^root/{print $1}END{print "over"}' passwd

    awk -F : '$1~/root/{print $1}' passwd 

    awk -F : '$7~/nologin$/{print $1}' passwd  

     

    课后练习

     

    练习1:

    在系统中列出所有能够使用的用户名称

    [root@westos_linux gz]# grep -E "bash$|sh$|tcsh$|csh$|tmux$" /etc/passwd | cut -d : -f 1 root daddy westos manalo lbj zxn

     

    练习2:

    制作一个脚本apache.sh,使得运行此脚本后输入数字可修改httpd端口为输入数字

    #!/bin/bash [ -z "$*" ] && { echo "Error: Please input the script!!" exit } [ -n "`netstat -antlupe | grep :$*`" ] && { echo "Error: the port is in used!!" exit } rpm -q httpd &> /dev/null_|| { echo "Error: please install httpd!!" exit } sed "/^Listen/cListen $*" /etc/httpd/conf/httpd.conf -i /etc/httpd/conf/httpd.conf systemctl restart httpd

     

    练习3:

    在系统中统计能被用户使用,并且家目录不在/home中的用户个数

    [root@westos_linux gz]# awk -F : 'BEGIN{N=0}$6!~/^\/home/&&/bash$|sh$|tcsh$/{N++}END{print N}' /etc/passwd 1 [root@westos_linux gz]# useradd -d /mnt bro useradd: warning: the home directory already exists. Not copying any file from skel directory into it. [root@westos_linux gz]# awk -F : 'BEGIN{N=0}$6!~/^\/home/&&/bash$|sh$|tcsh$/{N++}END{print N}' /etc/passwd 2

     

    Processed: 0.013, SQL: 9