Linux AWK 学习
Linux AWK 学习
创建文件
# vim emp.data
Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
简单的输出
1,NF,字段数量
AWK 计算当前输入行的字段数量,并将它存储在一个内建的变量中,这个变量叫做NF。
# awk '{print NF}' emp.data
3
3
3
3
3
3
2,计算和打印
也可以用字段的值进行计算,并将计算得到的结果放到输出语句中。
# awk '{print $1, $2 * $3}' emp.data
Beth 0
Dan 0
Kathy 40
Mark 100
Mary 121
Susie 76.5
3,打印行号
AWK 提供了另一个内建变量 NR,这个变量计算到目前为止,读取的行的数量。我们可以使用 NR 和 $0 为emp.data 的每一行加上行号。
# awk '{print NR, $0}' emp.data
1 Beth 4.00 0
2 Dan 3.75 0
3 Kathy 4.00 10
4 Mark 5.00 20
5 Mary 5.50 22
6 Susie 4.25 18
更精美的输出
1,字段排序
printf 语句格式如下:
printf( format, value1, value2, ..., vlaue$n$ )
format 是一个字符串,它包含按字面打印的文本,中间散布着格式说明符,格式说明符用于说明如何打印值。一个格式说明符是一个 %,后门跟这个几个符号,这些字符控制一个 value 的输出格式。第一个格式说明符说明 value1 的输出格式,第二个格式说明符说明 value2 ,依此类推。于是,格式说明符的数量应该和被打印的value 一样多。
这个程序使用printf 打印每位雇员的报酬:
# awk '{printf("total pay for %s is ¥%.2f \n", $1, $2 * $3)}' emp.data
total pay for Beth is ¥0.00
total pay for Dan is ¥0.00
total pay for Kathy is ¥40.00
total pay for Mark is ¥100.00
total pay for Mary is ¥121.00
total pay for Susie is ¥76.50
2,输出排序
设想以下你想要为每个雇员打印所有的数据,包括他的报酬,报酬按照升序排列。最简单的办法是使用 awk 在每一位雇员的记录前加上报酬,然后再通过一个排序程序进行排序。
# awk '{printf("%s %s\n", $2 * $3, $0)}' emp.data |sort -n
0 Beth 4.00 0
0 Dan 3.75 0
40 Kathy 4.00 10
76.5 Susie 4.25 18
100 Mark 5.00 20
121 Mary 5.50 22
选择
1,通过比较进行选择
条件大于等于 ¥5.00
# awk '$2 >= 5 {print $0}' emp.data
Mark 5.00 20
Mary 5.50 22
2,通过计算选择
大于超过 ¥50 的雇员
# awk '$2 * $3 > 50 {printf("%s for %s \n", $2 * $3, $1)}' emp.data
100 for Mark
121 for Mary
76.5 for Susie
3,通过文本内容选择
awk 也可以做到像grep 一样的操作,如下:
# awk '$1 == "Susie"' emp.data
Susie 4.25 18
4,模式的组合
模式可以使用括号和逻辑运算进行组合,逻辑运算包括 &&,||,和 ! ,分别表示 AND,OR,和 NOT 程序
# awk '$2 >= 4 || $3 >= 20' emp.data
Beth 4.00 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
BEGIN与END
特殊的模式BEGIN 在第一个输入文件的第一行之前被匹配,END 在最后一个输入文件的最后一行被处理之后匹配,以下使用BEGIN 打印一个标题:
# awk 'BEGIN {print "NAME RATE HOURS"; print ""} {print}' emp.data
NAME RATE HOURS
Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
可以在同一行放置多个语句,语句之间用分号分开。注意print "" 打印一个空行,它与一个单独的print 并不相同,后者打印当前行。