foreverys

导航

awk

相较于 sed 常常作用于一整个行的处理, awk 则比较倾向于一行当中分成数个『字段』来处理。 因此, awk 相当的适合处理小型的数据处理呢! awk 可以处理后续接的档案,也可以读取来自前个指令的 standard output 。

awk通常运作得模式

[root@linux ~]# awk '条件类型 1{动作 1} 条件类型 2{动作 2} ...' filename

例一:取出账号与登入者得 IP ,且账号与IP之间以[tab]隔开

[root@linux ~]# last | awk '{print $1 "\t" $3}'
dmtsai    192.168.1.12
root        Mon
reboot    boot
dmtsai    192.168.1.12
说明:
1.每一行的每个字段都是有变量名称的,那就是$1,$2... 等变量名称。例如dmtsai是$1,192.168.1.12是第三栏,所以他就是$3啦。
2.还有个$0,$0代表一整行的意思。

awk处理流程

1. 读入第一行,并将第一行的资料填入 $0, $1, $2.... 等变数当中;
2. 依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
3. 做完所有的动作与条件类型;
4. 若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。

awk内建变量

变量名称
代表意义
NF
每一行 ($0) 拥有的字段总数
NR
目前 awk 所处理的是『第几行』数据
FS
目前的分隔字符,预设是空格键
例二:列出每一行得账号,并且列出目前处理的行数,并且说明,该行有多少字段。
[root@linux ~]# last | awk '{print $1 "\t lines: " NR "\t columes: " NF}'
dmtsai    lines: 1    columes: 10
root        lines: 2    columes: 9
reboot    lines: 3    columes: 9
dmtsai    lines: 4    columes: 10

条件类型

awk 的逻辑运算字符

运算单元
代表意义
>
大于
<
小于
>=
大于或等于
<=
小于或等于
==
等于
!=
不等于

例三:在/etc/passwd当中是以冒号":"来作为字段的分隔,那假设我要查阅,第三栏小于30以下得数据,并且仅列出账号与第三栏。

linux-xuzz:~/test # cat /etc/passwd | awk '{FS=":"} $3<30 {print $1 "\t " $3}'
bin      1
daemon   2
games    12
。。。。。。
这样就可以显示出来了,但是有一个问题,第一行为什么没有正确得显示出来?
这是因为我们读入第一行的时候, 那些变数 $1, $2... 预设还是以空格键为分隔的,所以虽然我们定义了 FS=":" 了, 但是却仅能在第二行后才开始生效。

利用BEGIN关键词,可以预先设定awk的内建变量!

linux-xuzz:~/test # cat /etc/passwd | awk 'BEGIN {FS=":"} $3<30 {print $1 "\t " $3}'
at       25
bin      1
daemon   2
games    12

怎么样,第一行得at账户就显示出来啦,除了BEGIN之外,还有END关键字

例四:假设我有一个薪资数据表,如何帮我计算每个人的总额呢?而且我还想要格式化输出喔!

[root@linux ~]# cat pay.txt | \
> awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total" }
NR>=2{total = $2 + $3 + $4
printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}'
Name 1st 2nd 3th Total
VBird 23000 24000 25000 72000.00
DMTsai 21000 20000 23000 64000.00
Bird2 43000 42000 41000 126000.00
说明:
1.多个指令辅助时,可利用分号『 ;』间隔, 或者 直接以 [Enter] 按键来隔开每个指令。
2.在awk的动作里面,可以如同shell一样使用各式各样不同得命令。
3.另外一种使用if(条件)的方式:
[root@linux ~]# cat pay.txt | \
> awk '{if(NR==1) printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"} 
NR>=2{total = $2 + $3 + $4
printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}'

 

posted on 2015-08-11 12:50  foreverys  阅读(232)  评论(0编辑  收藏  举报