云服务器

文本三剑客之awk

2020-07-24 10:01:28 27

不可否认,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

上一篇: 无

微信关注

获取更多技术咨询