Awk一些用法记录

记录一些曾经用过的awk特殊用法。

分项记数

给出不同项的计数结果。

比如连接数:

1
2
3
4
netstat -an | awk '/^tcp/ {++a[$NF]}END{for(i in a) print i,a[i]}'
输出:
LISTEN 2
ESTABLISHED 9

这里a是一个字典,a[$NF]初始值为0,++a[$NF]等同于a[$NF]+=1,最后a的结果是{$NF: n}。再在结束时迭代字典得到结果。

取反

通常我们用awk ‘{print $1,$2,$3…}’来取想要的值,但如果值个数太多,又想取除$1外的值的话,可以用以下方法:

1
2
3
awk '{$1="";print}' /etc/hosts
输出:
localhost.localdomain localhost

把$1设为空值,再返回其它所有值,一样可以取得结果。

取指定列值

1
2
3
4
5
6
7
8
9
10
11
cat test.txt 
# 0.0.1
1 abc c
2 bcd 3
c ddd 4

awk '/^[^#]/{print $1,"abc",$3}' test.txt
输出:
1 abc c
2 abc 3
c abc 4

和与平均值

1
2
3
4
5
6
7
8
9
test.txt内容如下:
a 1
b 2
c 3
d 10

awk 'BEGIN{sum=0;count=0}{sum+=$2;count++}END{print "sum="sum" count="count" avg="sum/count}' test.txt
输出:
sum=16 count=4 avg=4

最大值

还是用上面那个test.txt示例。

1
2
3
awk 'BEGIN{max=0}{if($2>max) max=$2}END{print max}' test.txt
输出:
10

正则匹配

awk可以用match函数来匹配输出需要的字符。

1
2
3
4
5
6
7
8
test1.txt内容如下,需要匹配01跟10冒号后的字段。
a:12,01:901704,10:-MSJR,2:32,3:65
a:41,b:23,01:901765,9:02,10:-MSJR,8:90

cat test1.txt |awk '{match($0,/01:(\w+),(.*)?10:(-[[:upper:]]+),.*/,a);print a[1],a[3]}'
输出:
901704 -MSJR
901765 -MSJR

上面test1.txt里的字段是非固定的,无法使用awk -F来取需要的段,这时候可以试下match()。

格式:match(string,regexp,array)
string是内容,以awk -F分段,$0代表整行。
regexp是正则式,正则式需要用两个/括起来,即/regex/。
array是取匹配的内容,正则中用()取需要的内容,array[1]代表第一个(),array[2]代表第二个(),以此类推。


- - END - -


腾讯云
0%