文本三剑客之awk
不可否认,awk是Linux平台功能最强大的数据处理引擎,它提供了根式匹配、数学法算、流程控制、内置变量和函数等诸多强大的功能。它不仅仅是一个文本处理工具,还是一门程序设计语言。由于它过于强大和复杂,坊间流传过这样种说法: 一个Shel程序员对于awk的理解深度,甚至可以决定其代码水平的高低。
尽管awk的语法十分复杂,但它的本质始终还是模式+行为。一条完整的awk语句包含了BEGIN、END和中间三部分。BEGIN部分用于变量的初始化与赋值,END部分多用于输出结果。这两部分并不是必需的,只有当出现较为复杂的处理逻辑时,我们才会使用到它们。
1.统计数量
awk可以使用自增运算来构造计数功能。和grep不同,awk的统计功能是开放的,它可以实现针对各种操作的计数。下面这个示例展示的是统计匹配关键字git的行数。
[rootestation103 -]# awk /git/ /etc/shadow
gitlab-www:!!:173791::::::
git:!!:17379::::::
gitlab-redis:!!:17379::::::
gitlab psql:!!:17379::::::
gitlab-prometheus:!!:17379::::::
[root@station103 ~]# awk ‘/git/{n++} END {print n}’ /etc/shadow
2.获取某一行
NR是awk的内置变量,代表行号,如果要提取特定行,可以用它配合条件语句if来
实现
[root@station ~]# ps -C qemu-kvm
PID TTY TIME CMD
13588 ? 00:03:28 qemu-kvm
13638 ? 00:05:19 qemu-kvm
13678 ? 00:05:12 qemu-kvm
13727 ? 00:05:26 qemu-kvm
29357 ? 3-23:02:45 qemu-kvm
//使用NR类量提取上述输出的第6行
[root@station103 ~]# ps -C qemu-kvm l awk ’ { if (NR==6) print $0}’
29357 ? 3-23:02:45 qemu-kvm
3.比较
awk还有比较的功能,它可以根据比较结果,返回预先设定的值。下面这几个例子中,当a>b时,即结果为真,将返回1,否则返回0。在比较的过程中要注意变量的类型。当进行字符串比较时,2是大于10的。因为2的ASCII码大于1的ASCII码,这就是逐位出较产生的结果。
[root@station103 ~]# awk 'BDGIN(a=2;b=10;print (a>b) ?1:0}'
0
[root@station103 ~]# awk 'BEGIN(a="2";b="10";print (a>b) ?1:0)'
1
[root@station103 ~]# awk 'BEGIN{a="2";b="1";print (a>b) ?1:0)'
1
4.求和与求平均值
在当前的用户家目录中存在以下这些对象,其中第五列是Size,现在我们要求取这些对象的Size总和与平均值。
[root@station103 ~]# ll
total 72
-rw-r- -r-- 1 root root 13 Sep 20 17:57 1
-r-xr-xr-x 1 root root 4096 Aug 22 17:06 chroot
-rw-r--r-- 1 root root 60 Sep 21 15:56 data
-rw-r--r-- 1 root root 69 Sep 17 18:50 eval. Sh
-rw-r--r-- 1 root root 420 Sep 19 11:03 getopt1. sh
-rw-r--r-- 1 root root 457 Sep 19 17:59 getopt2. sh
-rw-r--r-- 1 root root 0 Sep 19 14:36 getopt -parse . bash
-rw-r--r-- 1 root root 272 Sep 18 16:53 menu. sh
-rwxr-xr-x 1 root root 20480 Aug 7 17:52 merge
-rw-r--r-- 1 root root 748 Sep 15 17:35 null. Sh
-rw-r--r- - 1 root root 27 Sèp 17 17:39 quotes. Sh
-rw-r--r-- 1 root root 200 Sep 15 16:31 return. Sh
-rw-r--r-- 1 root root 98 Sep 15 17:59 shift.sh
-rw------- 1 root root 100 Sep 20 16:04 text
-rwxr-xr-x 1 root root 4096 Sep 19 17:06 tmp
这一次有点复杂,我们要将awk分成两部分,先计算数据,再打印结果。首先,要过滤掉total这一行,叹号在这里代表逻辑非。其次,求和需要累加,求平均需要知道累加的次数,这里我们使用运算符+=来实现。这两个值都有着落了,最后我们就可以使用printf语句进行结果输出了。因为printf支持算术表达式,所以对平均值的求取也一并纳入END中。
[root@station103 ~]# ll | awk ‘!/total/ {sum+=$5;line+=1} END {printf “Sum = %d\nlines = %d\nAverage = %d\n”, sum,line,sum/line}’
Sum = 31136
Lines = 15
Average = 2075
睿江云官网链接:www.eflycloud.com