shell脚本编程之正则表达式(三)

一、前言

​ 前面两篇文章主要介绍了正则表达式的概念与作用,对基础正则表达式及扩展正则表达式进行概念叙述;同时介绍了shell“三剑客”中的grep与sed两个命令,本文将介绍最后一个剑客——awk。

​ 同时,我们还将介绍sort工具以及uniq工具。

二、awk工具

​ 在Linux/Unix系统中,awk是一个强大的编辑工具,逐行读取输入文本,并且根据指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理,可以在无交互的情况下实现相当复杂的文本操作,被广泛应用于 Shell 脚本,完成各种自动化配置任务。

常见用法

​ awk 选项 ’模式或条件 {编辑指令} ‘ 文件1 文件2

​ awk -f 脚本文件 文件1 文件2

​ sed命令常用于一整行的处理,awk则是将一行分为多个字段后再处理,而默认情况下字段的分隔符为空格或者TAB键。

​ awk 执行结果可以通过 print 的功能将字段数据打印显示。在使用 awk 命令的过程中,可以使用逻辑操作符“&&”,表示“与”, “||”表示“或”,“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别 表示加、减、乘、除、取余和乘方。

​ awk包含几个特殊的内建变量(无法修改但可以直接使用)

​ FS:指定每行文本的字段分隔符,默认为空格或者制表位(TAB)

​ NF:当前处理的行的字段个数

​ NR:当前处理的行的行号(序数)

​ $0:当前处理的行的内容

​ $n:当前处理行的第n个字段(第n列)

​ FILENAME:被处理的文件名

​ RS:数据记录分隔,默认为\n 即每行为一条记录

实例讲述:

1)查找出/etc/passwd文件中的用户名、用户ID、组ID列

[root@lokott ~]# awk -F: '{print $1,$3,$4}' /etc/passwd
root 0 0
bin 1 1
daemon 2 2
...//省略部分内容
[root@lokott ~]# awk -F: '{print $0}' /etc/passwd  //$0表示显示整个行,结果与cat 和sed -n 'p'等价
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
......//省略部分内容

2)按行输出文本

[root@lokott ~]# awk '{print}' /etc/passwd   //等同于 awk '{print $0}' /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

[root@lokott ~]# awk 'NR==1,NR==3{print}' /etc/passwd   //输出1-3的行内容,与下等同
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@lokott ~]# awk '(NR>=1)&&(NR<=3){print}' /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

[root@lokott ~]# awk '(NR==1)||(NR==3){print}' /etc/passwd  //输出第1和3行的内容
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin

[root@lokott ~]# nl /etc/passwd |awk 'NR%2==1{print}'  //输出奇数行内容
     1  root:x:0:0:root:/root:/bin/bash
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    ......//省略部分内容
[root@lokott ~]# nl /etc/passwd |awk 'NR%2==0{print}' //输出偶数行内容
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     6  sync:x:5:0:sync:/sbin:/bin/sync
     8  halt:x:7:0:halt:/sbin:/sbin/halt

[root@lokott ~]# awk '/^root/{print}' /etc/passwd  //输出以root开头的行
root:x:0:0:root:/root:/bin/bash
[root@lokott ~]# awk '/bash$/{print}' /etc/passwd   //输出以bash结尾的行
root:x:0:0:root:/root:/bin/bash
lokott:x:1000:1000:lokott:/home/lokott:/bin/bash
lisi:x:1002:1002::/home/lisi:/bin/bash

[root@lokott ~]# awk 'BEGIN{x=0};/\/bin\/bash$/ {x++};END {print x}' /etc/passwd
3
[root@lokott ~]# grep -c "/bin/bash$" /etc/passwd
3
//统计以/bin/bash结尾的行的数量

3)按字段输出文本

[root@lokott ~]# sed 's/:/ /g' /etc/passwd|awk '{print $1,$3}'|tail -3
named 25
apache 48
lisi 1002
//将passwd文件中的所有:替换为空格后的内容到缓存中,然后使用awk命令输出每行的第一和第三个字段到管道中,最后输出最后三行到显示屏上,也可以在后面继续添加“|sort”继续排序

[root@lokott ~]# awk -F: '$2=="!!"{print}' /etc/shadow |tail -3
tcpdump:!!:18214::::::
named:!!:18220::::::
apache:!!:18228::::::
//输出密码为!!(没有密码的)的用户的shadow记录
[root@lokott ~]# awk -F: '$7~"/bash"{print $1}' /etc/passwd//输出第七个字段中包含/bash的行的第一个字段
root
lokott
lisi
[root@lokott ~]# awk '($1~"nfs")&&(NF==8){print $1,$2}' /etc/services 
nfs 2049/tcp                            //输出包含8个字段且第一个字段包含nfs的行的第1、2个字段
nfs 2049/udp
nfs 2049/sctp
netconfsoaphttp 832/tcp
netconfsoaphttp 832/udp
netconfsoapbeep 833/tcp
netconfsoapbeep 833/udp

4)通过管道、双引号调用shell命令

[root@lokott ~]# awk '/bash$/{print |"wc -l"}' /etc/passwd
3
//输出使用bash的用户个数

三、sort工具和uniq工具

​ 在Linux系统中,常用的文件排序工具有三种:sort、uniq、wc。wc在linux命令章节中讲解了,一般用于统计,因此这里不再赘述。主要讲解sort和uniq工具的用途和使用方法。

1.sort

​ sort是一个以行为单位对文件内容进行排序的工具,也可以根据不同的数据类型来排序。

​ 使用格式:sort [选项] 参数

​ 选项:

  • -f:忽略大小写;
  • -b:忽略每行前面的空格;
  • -M:按照月份进行排序;
  • -n:按照数字进行排序;
  • -r:反向排序;(常用)
  • -u:等同于 uniq,表示相同的数据仅显示一行;
  • -t:指定分隔符,默认使用[Tab]键分隔;
  • -o <输出文件>:将排序后的结果转存至指定文件;(常用)
  • -k:指定排序区域。

实例:

[root@lokott ~]# sort /etc/passwd |nl       //依据字母排序正向
     1  abrt:x:173:173::/etc/abrt:/sbin/nologin
     2  adm:x:3:4:adm:/var/adm:/sbin/nologin
     3  apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
     4  avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
     5  bin:x:1:1:bin:/bin:/sbin/nologin
     ......//省略部分内容
[root@lokott ~]# sort -r /etc/passwd |nl   //依据字母排序反向
     1  usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
     2  tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
     3  tcpdump:x:72:72::/:/sbin/nologin
     4  systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
     5  sync:x:5:0:sync:/sbin:/bin/sync
     ......//省略部分内容
[root@lokott ~]# sort -t: -k 1 /etc/passwd  //根据:号将第一列进行正向排序
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
chrony:x:995:991::/var/lib/chrony:/sbin/nologin
colord:x:997:995:User for colord:/var/lib/colord:/sbin/nologin
......//省略部分内容

[root@lokott ~]# sort -t: -k 1 /etc/passwd -o out.txt  //将上述结果输入到文件out.txt中
[root@lokott ~]# cat out.txt 
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
......//省略部分内容

2.uniq

uniq工具在Linux系统中通常与sort命令结合使用,用于报告或者忽略文件中的重复行。

格式:uniq [选项] 参数

选项:

-c:进行计数

-d:仅显示重复行

-u:仅显示出现一次的行

实例:

[root@lokott ~]# cat test.txt  //有空行
this is a test
this is a test
this is a test

hello
hello

world 

this is a test
this is a test
list
list

hostname
hostname

[root@lokott ~]# uniq test.txt   //删除互相连续的重复的行
this is a test

hello

world 

this is a test
list

hostname

[root@lokott ~]#uniq -c test.txt  //行前显示该行重复出现的此次数
      3 this is a test
      1 
      2 hello
      1 
      1 world 
      2 
      2 this is a test
      2 list
      1 
      2 hostname
      1 
[root@lokott ~]# uniq -d test.txt  //删除连续重复的重复行
this is a test
hello

this is a test
list
hostname

四、小结

​ 本文主要讲解的是awk、sort以及uniq工具的用途以及使用方法,结合实例来解释。