统计

一个动作就是一个以新行或者分号分隔的语句序列。

不仅可以使用像 NF 这样的内置变量,还可以创建自己的变量用于计算、存储数据诸如此类的操作。awk中,用户创建的变量不需要声明

计数

# 使用emp变量统计第三个字段大于15行数
$3 > 15 { emp = emp + 1 }
END     { print emp, "more than 15" }

用作数字的awk变量的默认初始值为0,所以不需要初始化 emp 。

求和与平均值

使用内置变量 NR ,它保存着到目前位置读取的行数;在所有输入的结尾它的值就是所读的所有行数。

# 求和,计算总行数
END { print NR }
# 求和,计算每一行的第二个字段和第三个字段的乘积的和
{ pay = pay + $2 * $3 }
END { print NR, "employees"
  print "total pay is", pay
# 计算均值,总和除以总行数
  print "average pay is", pay/NR
}

该程序也有个潜在的错误:在某种不太可能发生的情况下, NR 等于0,那么程序会试图执行零除,从而产生错误信息。

统计

计算所有的C文件,CPP文件和H文件的文件大小总和:

$ ls -l  *.cpp *.c *.h | awk '{sum+=$5} END {print sum}'
2511401

统计各个connection状态的用法:(可以看到一些编程的影子了,注意其中的数组的用法)

$ awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}' netstat.txt
TIME_WAIT, 3
FIN_WAIT1, 1
ESTABLISHED, 6
FIN_WAIT2, 3
LAST_ACK, 1
LISTEN, 4

统计每个用户的进程的占了多少内存:(注:sum的RSS那一列)

$ ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'
dbus, 540KB
mysql, 99928KB
www, 3264924KB
root, 63644KB
hchen, 6020KB

处理文本

awk的优势之一是能像大多数语言处理数字一样方便地处理字符串。awk变量可以保存数字也可以保存字符串。

#如果有多行匹配模式时,变量中只会保存第一个找到的行中的字符串
$2 > maxrate { maxrate = $2; maxemp = $1 }
END { print "highest hourly rate:", maxrate, "for", maxemp }

这个程序中,变量 maxrate 保存着一个数值,而变量 maxemp 则是保存着一个字符串。

字符串连接

可以合并老字符串来创建新字符串。这种操作称为 连接(concatenation)。

# 通过将每个姓名和一个空格附加到变量 names 的前一个值, 来将所有员工的姓名收集进单个字符串中。最后 END 动作打印出 names 的值。
{ names = names $1 " "}
END { print names }

awk程序中,连接操作的表现形式是将字符串值一个接一个地写出来。

对于每个输入行,程序的第一个语句先连接三个字符串: names 的前一个值、当前行的第一个字段以及一个空格,然后将得到的字符串赋值给 names 。因此,读取所有的输入行之后, names 就是个字符串,包含所有员工的姓名,每个姓名后面跟着一个空格。用于保存字符串的变量的默认初始值是空字符串(也就是说该字符串包含零个字符),因此这个程序中的 names 不需要显式初始化。

打印最后一个输入行

虽然在 END 动作中 NR 还保留着它的值,但 $0 没有。

END { print $0 }

是打印最后一个输入行的一种方式。

内置函数

awk提供了内置变量来保存某些频繁使用的数量,比如:字段的数量输入行的数量

类似地,也有内置函数用来计算其他有用的数值。除了平方根对数随机数诸如此类的算术函数,也有操作文本的函数。其中之一是length ,计算一个字符串中的字符数量。

{ print $1, length($1) }

行、单词以及字符的计数

这个程序使用了 length 、 NF 、以及 NR 来统计输入中行、单词以及字符的数量。为了简便,我们将每个字段看作一个单词。

# $0 并不包含每个输入行的末尾的换行符,所以我们要另外加个1。
    { nc = nc + length($0) + 1
      nw = nw + NF
    }
END { print NR, "lines,", nw, "words,", nc, "characters" }

最后更新于

这有帮助吗?