本篇记录awk中操作符的实例
1. 为输入域设置变量名
awk '{name=$1;belts=$4; if(belts ~/Yellow/) print name "is belt" belts}' grade.txt
P.Bunnyis beltYellow
为输入域设置域变量名,引用变量的时候直接使用变量名即可。
上例将域$1命名为name,域$4命名为belts
2. 域值比较操作
1) 在BEGIN中给域变量赋值,下例中27可以加引号,也可不加
awk 'BEGIN {BASELINE="27"} {if($6 < BASELINE)print $0}' grade.txt
J.Lulu 06/99 48317 green 9 24 26
J.Troll 07/99 4842 Brown-3 12 26 26
2)在关系操作中使用实际数值
awk '{if($6 < 27)print $0}' grade.txt
J.Lulu 06/99 48317 green 9 24 26
J.Troll 07/99 4842 Brown-3 12 26 26
3. 修改数值域取值
awk '{if($1 == "M.Tansley") $6=$6-1;print $1,$6,$7}' grade.txt
M.Tansley 39 44
J.Lulu 24 26
P.Bunny 35 28
J.Troll 26 26
L.Tansley 30 28
注意,awk的修改只针对awk读入的副本,不是针对原文本,可以用重定向,将修改后的结果保存至文件
4. 修改文本域取值
awk '{if ($1 == "J.Troll") ($1 ="J.L.Troll");print $1}' grade.txt
M.Tansley
J.Lulu
P.Bunny
J.L.Troll
L.Tansley
注意,字符串要用双引号,赋值语法最好用()括起来,提高可读性及健壮性。
5. 只显示修改记录
awk '{if ($1 == "J.Troll") {$1 ="J.L.Troll";print $1}}' grade.txt
J.L.Troll
注意本例与上一例的区别,本例中,先取得模式,再根据模式进行修改和打印。
这样,就只会打印和模式匹配的行。
6. 创建新的输出域
awk 'BEGIN {print "name\t Difference"} {if($6 < $7) {$8=$7-$6; print $1,$8}}' grade.txt
name Difference
M.Tansley 4
J.Lulu 2
也可以给新添加的域取变量名,下例中,新加的域为diff
awk 'BEGIN {print "Name\t Difference"} {if($6<$7){diff=$7-$6;print $1,diff}}' grade.txt
Name Difference
M.Tansley 4
J.Lulu 2
7. 列值叠加
awk '(total+=$6); END {print "Club student total points: " total}' grade.txt
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
Club student total points: 155
列值的叠加使用操作符 += ,awk 模式打印匹配的内容,所以可以不加print语句。
如果只想打印最后的统计结果,而不想输出文件内容,则在计算结果的语法外面加上花括号{}
awk '{(total+=$6)}; END {print "Club student total points: " total}' grade.txt
Club student total points: 155
8. 计算文件长度
ls -l | awk '$0 !~ /(^d)/ {(total+=$5);print $9,$5} END {print "------\ntotal size: "total}'
1.txt 179
2.txt 27
grade.txt 220
modified.txt 73
myfile 27
------
total size: 526
将ls -l 的结果通过管道传给awk,awk用正则表达式过滤掉目录,再通过列叠加的方法结算当前目录下所有文件的总大小。