一、awk的作用
相较于sed常常作用于行的处理,awk则比较倾向于一行当中分成数个“字段”来处理。因此,awk相当适合处理小型的数据。
二、awk的用法总结
1.语法格式
awk + options(选项) + program(命令) + file(文件)
awk后面接两个单引号并加上大括号来设置想要对数据进行的处理动作。awk可以处理后续接的文件,也可以读取来自前个指令的standard output。但如前面所说,awk主要是处理“每一行的字段内的数据”,而默认的“字段的分隔符号为"空白键"或"tab键"。
2.举例说明
(1)用last可以将登陆者的数据打印出前5行
[root@localhost ~]# last -n 5
root pts/0 192.168.229.1 Thu Jun 25 18:17 still logged in
reboot system boot 3.10.0-1127.8.2. Thu Jun 25 18:16 - 18:17 (00:01)
root pts/4 192.168.229.1 Wed Jun 24 18:08 - crash (1+00:08)
root pts/3 192.168.229.1 Sun Jun 21 14:36 - 10:53 (3+20:16)
root pts/2 192.168.229.1 Sun Jun 21 10:53 - 10:49 (3+23:56)
wtmp begins Tue Apr 14 14:54:25 2020
(2)若只想要取出帐号与登陆者的IP,且帐号与IP之间以tab键隔开,就可以这样操作。
[root@localhost ~]# last -n 5 | awk '{print $1 "\t" $3}'
root 192.168.229.1
reboot boot
root 192.168.229.1
root 192.168.229.1
root 192.168.229.1
wtmp Tue
3.awk处理流程
(1)读入第一行,并将第一行的数据填入$0,$1,$2....等变量当中;
(2)依据"条件类型"的限制,判断是否需要进行后面的"动作";
(3)做完所有的动作与条件类型;
(4)若还有后续的“行”的数据,则重复上面1~3的步骤,直到所有的数据都读完为止;
经过这样的步骤,可以知道awk是“以行为一次处理”,而“以字段为最小的处理单位”。那么awk怎么知道这个数据有几行?有几栏呢?这就需要awk的内置变量了。
4.awk内置变量
变量名称 | 代表意义 |
---|---|
NF | 每一行($0)拥有的字段总数。 |
NR | 目前awk处理的是第几行数据。 |
FS | 目前的分隔字符,默认是空白键。 |
5.继续上面的举例
列出每一行的帐号就是($1);
列出目前处理的行数(就是awk内的NR变量);
并且说明,该行有多少字段(就是awk内的NF变量);
awk后续的所有动作是以单引号括住的,由于单引号与双引号都必须是成对的. 所以, awk的格式内容如果想要以print打印。
[root@localhost ~]# last -n 5 | awk '{print $1 "\t line:" NR "\t count:" NF}'
root line:1 count:10
reboot line:2 count:11
root line:3 count:10
root line:4 count:10
root line:5 count:10
line:6 count:0
wtmp line:7 count:7
三、awk的逻辑运算字符
运算单元 | 代表意义 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
== | 等于 |
!= | 不等于 |
举例来说,在/etc/passwd当中是以冒号":"来作为字段的分隔,该文件中第一字段为帐号,第三字段则是UID。假设我要查阅第三栏小于10以下的数据,并且仅列出帐号与第三栏,那么可以这样做:
[root@localhost ~]# cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "\t" $3}'
root:x:0:0:root:/root:/bin/bash
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
可以看到第一行没有正确的显示出来。这是因为我们读入第一行的时候,那些变量$1,$2…默认还是以空白键为分隔的,所以虽然定义了FS=":",但是却仅能在第二行后才开始生效。怎么办呢?我们可以预先设置awk的变量。利用BEGIN这个关键字可以完成要求。
[root@localhost ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3<10 {print $1 "\t" $3}'
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8