正则表达基础命令

   正则表达的基础知识已经在上一节讲过,下面要讲的是正则表达的三个关键命令grep、sed、awk。

  1)grep 用于过滤行信息

  作用:查找打印找与关键词匹配的行

  参数:-n 在输出匹配行及行号一起输出;-v 打印不符合要求的行(取反);-i 不区分大小写;-w 打印完整单词的行;-An 打印符合要求的行以及下面n行;-Bn 打印符合要求的行以及上面n行;-Cn 打印符合要求的行以及上下n行。

  [root@centos7 ~]# grep -A2 'halt' /etc/passwd     #把包含halt的行及其下面的两行输出
  [root@centos7 ~]# grep -B2 'halt' /etc/passwd     #把包含halt的行及其上面的两行输出
  [root@centos7 ~]# grep -C2 'halt' /etc/passwd     #把包含halt的行及其上下各两行输出
  [root@centos7 ~]# grep -n 'root' /etc/passwd      #过滤出带有root关键字的行及行号
  [root@centos7 ~]# grep -v 'nologin' /etc/passwd     #过滤不带有nologin的行
  [root@centos7 ~]# grep '[0-9]' /etc/inittab           #过滤出所有包含数字的行
  [root@centos7 ~]# grep -v '[0-9]' /etc/inittab        #过滤出所有不包含数字的行
  [root@centos7 ~]# grep -v '^#' /etc/inittab           #过滤出非#开头的行
  [root@centos7 ~]# grep  'game$' /etc/inittab         #过滤出以game结尾的行
  [root@centos7 ~]# grep -v '^#' /etc/crontab |grep -v '^$'   #去除所有空行和以#开头的行

  2)sed 用于行文本的过滤和替换

  sed是一种在线编辑器,一次处理一行文本内容。处理时,把当前处理的行存储在临时缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。

  作用:过滤查询和修改替换文本内容

  参数:-n 只有经过sed 特殊处理的那一行(或者动作)才会被列出来;-e 直接在命令列模式上进行 sed 的动作编辑;-f 直接将 sed 的动作写在一个文件内;-r sed 的动作支持的是延伸型正规表示法的语法;-i 直接修改读取的文件内容,不输出到终端。a 新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行);c 取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行;d 删除,因为是删除啊,所以 d 后面通常不接任何内容;i 插入修改, i 的后面可以接字串,而这些字串会是新的一行;p 列印,将某个选择的数据输出;s 替换取代,直接进行取代;g 选择全部内容。

  删除:d命令 
  [root@centos7 ~]# sed '2d' app.txt       #删除文件的第二行
  [root@centos7 ~]# sed '2,$d' app.txt        #删除文件的第二行到末尾所有行
  [root@centos7 ~]# sed '$d' app.txt       #删除文件的最后一行
  [root@centos7 ~]# sed '/test/'d app.txt    #删除文件所有包含test的行

  替换:s命令 
  [root@centos7 ~]# sed 's/test/prod/g' app.txt  #文件中所有test替换为prod,无g则替换每行第一个
  [root@centos7 ~]# sed -n 's/^test/prod/p' app.txt  #开头为test的行,把test替换为prod并输出
  [root@centos7 ~]# sed -n 's/\(love\)able/\1rs/p' app.txt  #所有loveable会被替换成lovers 
  [root@centos7 ~]# sed 's#you#your#g' app.txt  # “#”在这里是分隔符,代替了默认的“/”

扫描二维码关注公众号,回复: 12105108 查看本文章

  选定行范围:逗号 
  [root@centos7 ~]# sed -n '/test/,/chart/p' app.txt    #输出所有在test和cheart范围内的行
  [root@centos7 ~]# sed -n '6,/^test/p' app.txt    #输出从第6行开始到以test开头行之间的所有行
  [root@centos7 ~]# sed '/test/,/chart/s/$/test/' app.txt  #test和west之间的行,末尾加上test

  多点编辑:e命令
  [root@centos7 ~]# sed -e '1,5d' -e 's/test/dev/' app.txt  #删除1至5行,并用dev替换test

  从文件读入:r命令 
  [root@centos7 ~]# sed '/test/r 1.txt' app.txt  #匹配test行,在该行插入1.txt内容一起输出

  写入文件:w命令 
  [root@centos7 ~]# sed -n '/test/w 1.txt' app.txt  #在app.txt中所有包含test的行都被写入1.txt

  追加命令:a命令 
  [root@centos7 ~]# sed '/^test/a\\--->this is app.txt' app.txt<  #内容被追加到以test开头行后面

  插入修改:i命令
  [root@centos7 ~]# sed '2i love you' app.txt     #在第2行插入love you
  [root@centos7 ~]# sed -i 's/\$/\!/g' app.txt     #将行尾的$替换为!

  3)awk 过滤编辑文本

  awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,按行处理文本。awk比sed更加强大,它能做到sed能做到的,也能做更复杂的正则。

  1 awk命令形式
    awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
    [-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
    ' '   # 引用代码块
    BEGIN   #初始化代码块,主要是引用全局变量,设置FS分隔符
    //   # 匹配代码块,可以是字符串或正则表达式
    {}   # 命令代码块,包含一条或多条命令
    ;   # 多条命令使用分号分隔
    END   # 结尾代码块,主要是进行最终计算或输出结尾摘要信息

  2 特殊变量符
    $0         # 表示整个当前行
    $1         #每行第一个字段
    NF         #字段数量变量
    NR         #每行的记录号,多文件记录递增
    FNR        # 与NR类似,多文件记录不递增,每个文件都从1开始
    \t          # 制表符
    \n          # 换行符
    FS         # BEGIN时定义分隔符
    RS         # 输入记录分隔符, 默认为换行符
    ~         # 匹配,与==相比不是精确比较
    !~         # 不匹配,不精确比较
    ==         # 等于,必须全部相等,精确比较
    !=         # 不等于,精确比较
    &&        # 逻辑与
    ||         # 逻辑或
    +         # 匹配时表示1个或1个以上
    /[0-9][0-9]+/     # 两个或两个以上数字
    /[0-9][0-9]*/     # 一个或一个以上数字
    OFS       # 输出字段分隔符, 默认也是空格
    ORS       # 输出记录分隔符,默认为换行符
    -F'[:#/]'     # 定义三个分隔符

  3 awk 示例

  截取文档中的某个段
  [root@centos7 ~]# head -n2 /etc/passwd |awk -F ':' '{print $1}'   #-F 是指定分隔符为:,默认以空格或tab为分隔符
  [root@centos7 ~]# head -n2 test.txt |awk -F':' '{print $0}'     #$0 是指输出整行
  
  匹配字符或字符串
  [root@centos7 ~]# awk '/oo/' app.txt           #匹配字符oo
  [root@centos7 ~]# awk -F ':' '$1 ~/oo/' app.txt       #匹配第一个字段中的字符oo
  [root@centos7 ~]# awk -F ':' '/ro/ {print $3} /te/ {print $3}' /etc/passwd   #awk可以多次匹配
  
  条件操作
  awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来后,那么awk不会认为是数字,而认为是字符,不加双引号则认为是数字。
  [root@centos7 ~]# awk -F ':' '$3=="0"' /etc/passwd     #匹配第三个字段带有字符0的行
  [root@centos7 ~]# awk -F ':' '$3>=500' /etc/passwd     #匹配第三个字段大于数字500的行
  [root@centos7 ~]# awk -F ':' '$7!="/sbin/nologin"' /etc/passwd   #匹配第七个字段不是nologin的行
  [root@centos7 ~]# awk -F ':' '$3<$4' /etc/passwd       #两个段之间进行逻辑比较
  [root@centos7 ~]# awk -F ':' '$3>"5" && $3<"7"' /etc/passwd   #同时满足两个匹配条件的行
  [root@centos7 ~]# awk -F ':' '$3>"5" || $7=="/bin/bash"' /etc/passwd   #满足其中一个条件的行
  
  常用的变量
  NF :用分隔符分隔后一共有多少段,NF是多少段,而$NF是最后一段的值
  NR :行数行号
  [root@centos7 ~]# head -n3 /etc/passwd | awk -F ':' '{print NF}'     #输出总段数
  [root@centos7 ~]# head -n3 /etc/passwd | awk -F ':' '{print $NF}'   #输出最后一段的值
  [root@centos7 ~]# head -n3 /etc/passwd | awk -F ':' '{print NR}'   #输出行号
  [root@centos7 ~]# awk 'NR>20' /etc/passwd         #使用行号20作为判断条件
  [root@centos7 ~]# awk -F ':' 'NR>20 && $1 ~ /ssh/' /etc/passwd   #输出NR大于20且第一段有ssh的行
  
  修改计算字段值
  [root@centos7 ~]# head -n3 /etc/passwd |awk -F ':' '$1="root"'   #前三行第一段修改为root输出
  [root@centos7 ~]# head -n2 /etc/passwd |awk -F ':' '{$7=$3+$4; print $7}'   #计算字段并赋值
  [root@centos7 ~]# awk -F ':' '{(t=t+$3)}; END {print t}' /etc/passwd   #$3字段计和
  [root@centos7 ~]# awk -F ':' '{if ($1=="root") print $0}' /etc/passwd    #输出$1为root的行

  本节的内容都是基础,上面的命令示例,可以满足日常使用,若要更复杂强大的功能,可以到命令工具官网查看。尤其是awk,有专业的书籍介绍该命令工具。命令的熟悉是写脚本的前提,在写一个脚本前,首先要清楚命令各个命令的执行结果,配合判断循环语句,实现批量复杂的处理功能。


猜你喜欢

转载自blog.51cto.com/superleedo/2551502