目录
展开
一、awk数组去除重复行
root@debian:~/awk# cat x.log
abc
def
ghi
abc
ghi
xyz
mnopq
abc
root@debian:~/awk# awk '{arr[$0]++}END{for(i in arr)print i}' x.log ###由于用了for循环,遍历是无序的
def
mnopq
abc
ghi
xyz
如果想不打乱顺序按原样输出,则不能使用for
:
root@debian:~/awk# awk '!arr[0]++{print0}' x.log
abc
def
ghi
xyz
mnopq
root@debian:~/awk
分析:!arr[$0]++
作为partten
,只有第一次出现的值为空(为假),取反后则为真,执行main
代码块
二、指定遍历顺序
awk数组为关联数组,默认情况下,for(idx in arr)
遍历数组时顺序是不可预测的。
但gawk提供了PROCINFO["sorted_in"]
来指定遍历的元素顺序。它可以设置为两种类型的值:
– 设置为用户自定义函数
– 设置为下面这些awk预定义好的值:
预定义值 | 说明 |
---|---|
@unsorted |
默认值,遍历时无序 |
@ind_str_asc |
索引按字符串比较方式升序遍历 |
@ind_str_desc |
索引按字符串比较方式降序遍历 |
@ind_num_asc |
索引强制按照数值比较方式升序遍历,无法转换的字符串索引将当做数值0进行比较 |
@ind_num_desc |
索引强制按照数值比较方式降序遍历,无法转换的字符串索引将当做数值0进行比较 |
@val_type_asc |
按值升序比较,数值类型>字符串类型>数组类型,即num>str>arr |
@val_type_desc |
按值降序比较,数值类型<字符串类型<数组类型,即num<str<arr |
@val_str_asc |
按值升序比较,数值转化成字符串再比较,而数组出现在尾部 |
@val_str_desc |
按值降序比较,数值转化成字符串再比较,而数组出现在头部 |
@val_num_asc |
按值升序比较,字符串转换为数值再比较,而数组出现在尾部 |
@val_num_desc |
按值降序比较,字符串转化成数值再比较,而数组出现在头部 |
- 示例一,按值降序排序
root@debian:~/awk# awk '{arr[0]=0;PROCINFO["sorted_in"]="@val_num_desc"}END{for(idx in arr)print arr[idx]}'< <(seq 6)
6
5
4
3
2
1
root@debian:~/awk#
- 示例二,按索引降序排序
root@debian:~/awk# awk '{arr[0]=0;PROCINFO["sorted_in"]="@ind_num_desc"}END{for(idx in arr)print idx"-->"arr[idx]}'< <(seq 6)
6-->6
5-->5
4-->4
3-->3
2-->2
1-->1
root@debian:~/awk
三、awk统计行和单词出现次数
- 示例一,统计次数并按照值排序:
root@debian:~/awk# awk '{arr[$0]++;PROCINFO["sorted_in"]="@val_num_asc"}END{for(idx in arr)print idx"-->"arr[idx]}' x.log
-->1
def-->1
mnopq-->1
xyz-->1
ghi-->2
abc-->3
root@debian:~/awk#
- 示例二,统计单词出现次数:
root@debian:~/awk# cat x.log
abc
def abc
ghi
abc word
ghi hello
xyz world
mnopq
abc
root@debian:~/awk# awk '{for(i=1;i<=NF;i++){arr[$i]++}}END{for(idx in arr)print idx":"arr[idx]}' x.log
hello:1
def:1
mnopq:1
abc:4
world:1
ghi:2
xyz:1
word:1
root@debian:~/awk#
- 示例三,统计
tcp[6]
出现的state
次数
root@debian:~/awk# netstat -tanp|awk '/tcp6?/{arr[$6]++}END{for(idx in arr)print idx":"arr[idx]}'
LISTEN:20
CLOSE_WAIT:126
ESTABLISHED:4
root@debian:~/awk#
四、根据字段取出最大值
root@debian:~/awk# cat aaa.txt
file 100
dir 11
file 100
dir 11
file 102
dir 112
file 120
dir 119
root@debian:~/awk# awk '{if(arr[1]<2){arr[1]=2}}END{for(idx in arr) print idx":"arr[idx]}' aaa.txt
dir:119
file:120
root@debian:~/awk#
使用三目运算法简化:
root@debian:~/awk# awk '{arr[1]=(2>arr[1]) ?2: arr[$1]}END{for(i in arr)print i":"arr[i]}' aaa.txt
dir:119
file:120
五、awk复合索引数组
- 示例,逆时针倒转数据:
root@debian:~/awk# cat c.txt
1 2 3 4 5 6
2 3 4 5 6 1
3 4 5 6 1 2
4 5 6 1 2 3
root@debian:~/awk# awk '{nf=NF;nr=NR;for(i=1;i<=NF;i++){arr[NR,i]=i}}END{for(i=1;i<=nf;i++){for(j=nr;j>=1;j--)if(j==1)printf "%s\n",arr[j,i];else printf "%s ",arr[j,i]}}' c.txt
4 3 2 1
5 4 3 2
6 5 4 3
1 6 5 4
2 1 6 5
3 2 1 6
root@debian:~/awk# awk '{nf=NF;nr=NR;for(i=1;i<=NF;i++){arr[NR,i]=i}}END{for(i=1;i<=nf;i++){for(j=nr;j>=1;j--)if(j%nr==1)printf "%s\n",arr[j,i];else printf "%s ",arr[j,i]}}' c.txt
4 3 2 1
5 4 3 2
6 5 4 3
1 6 5 4
2 1 6 5
3 2 1 6
root@debian:~/awk#
将数组元素按照[NR,NF]
的格式存储,END
读取完整个文件并初始化数组之后,使用for
循环格式化输出即可。
六、测试数据类型是否为数组
isarray(arr)
可用于检测arr
是否为数组,是则返回1,否则返回0。- 对比
typeof(arr)
可返回arr
的数据类型,如果arr
为数组,则返回”array”
示例:
root@debian:~/awk# awk 'BEGIN{arr[a]="a";print typeof(arr)=="array";print isarray(arr);arr["null"];print length(arr)}'
1
1
2
root@debian:~/awk#