awk 数组--心得
上一篇 /
下一篇 2011-08-01 00:26:13
/ 个人分类:AWK学习
在文本处理的工作中,awk的数组是必不可少的工具,在这里,同样以总结经验和教训的方式和大家分享下我的一些学习心得,如有错误的地方,请大家指正和补充。
awk的数组,一种关联数组(Associative Arrays),下标可以是数字和字符串。因无需对数组名和元素提前声明,也无需指定元素个数 ,所以awk的数组使用非常灵活。
首先介绍下几个awk数组相关的知识点:
<1>建立数组- array[index] = value :数组名array,下标index以及相应的值value。
复制代码 <2>读取数组值- { for (item in array) print array[item]} # 输出的顺序是随机的
- {for(i=1;i<=len;i++) print array[i]} # Len 是数组的长度
复制代码 <3>多维数组,array[index1,index2,……]:SUBSEP是数组下标分割符,默认为“\034”。可以事先设定SUBSEP,也可以直接在SUBSEP的位置输入你要用的分隔符,如:- awk 'BEGIN{SUBSEP=":";array["a","b"]=1;for(i in array) print i}'
- a:b
- awk 'BEGIN{array["a"":""b"]=1;for(i in array) print i}'
- a:b
复制代码 但,有些特殊情况需要避免,如:- awk 'BEGIN{
- SUBSEP=":"
- array["a","b:c"]=1 # 下标为“a:b:c”
- array["a:b","c"]=2 #下标同样是“a:b:c”
- for (i in array) print i,array[i]}'
- a:b:c 2 #所以数组元素只有一个。
复制代码 <4>删除数组或数组元素: 使用delete 函数- delete array #删除整个数组
- delete array[item] # 删除某个数组元素(item)
复制代码 <5> 排序:awk中的asort函数可以实现对数组的值进行排序,不过排序之后的数组下标改为从1到数组的长度。在gawk 3.1.2以后的版本还提供了一个asorti函数,这个函数不是依据关联数组的值,而是依据关联数组的下标排序,即asorti(array)以后,仍会用数字(1到数组长度)来作为下标,但是array的数组值变为排序后的原来的下标,除非你指定另一个参数如:asorti(a,b)。(非常感谢lionfun对asorti的指正和补充)
- echo 'aa
- bb
- aa
- bb
- cc' |\
- awk '{a[$0]++}END{l=asorti(a);for(i=1;i<=l;i++)print a[i]}'
- aa
- bb
- cc
- echo 'aa
- bb
- aa
- bb
- cc' |\
- awk '{a[$0]++}END{l=asorti(a,b);for(i=1;i<=l;i++)print b[i],a[b[i]]}'
- aa 2
- bb 2
- cc 1
复制代码
下面说awk数组的实际应用。
1. 除去重复项, 这个不多说, 只给出代码:- awk '!a[$0]++' file(s)
- awk '!($0 in a){a[$0];print}' file(s)
复制代码 另一种:http://bbs.chinaunix.net/thread-1859344-1-1.html
2. 计算总数(sum),如:- awk '{name[$0]+=$1};END{for(i in name) print i, name[i]}'
- 再举个例子:
- echo "aaa 1
- aaa 1
- ccc 1
- aaa 1
- bbb 1
- ccc 1" |awk '{a[$1]+=$2}END{for(i in a) print i,a[i]}'
- aaa 3
- bbb 1
- ccc 2
复制代码 3. 查看文件差异。- cat file1
- aaa
- bbb
- ccc
- ddd
- cat file2
- aaa
- eee
- ddd
- fff
复制代码 <1> 合并file1和file2,除去重复项:- awk 'NR==FNR{a[$0]=1;print} #读取file1,建立数组a,下标为$0,并赋值为1,然后打印
- NR>FNR{ #读取file2
- if(!(a[$0])) {print } #如果file2 的$0不存在于数组a中,即不存在于file1,则打印。
- }' file1 file2
- aaa
- bbb
- ccc
- ddd
- eee
- fff
复制代码 <2> 提取文件1中有,但文件2中没有:- awk 'NR==FNR{a[$0]=1} #读取file2,建立数组a,下标为$0,并赋值为1
- NR>FNR{ #读取file1
- if(!(a[$0])) {print } #如果file1 的$0不存在于数组a中,即不存在于file2,则打印。
- }' file2 file1
- bbb
- ccc
复制代码 另:http://bbs.chinaunix.net/viewthr ... &page=1#pid15547885
4. 排序:- echo "a
- 1
- 0
- b
- 2
- 10
- 8
- 100" |
- awk '{a[$0]=$0} #建立数组a,下标为$0,赋值也为$0
- END{
- len=asort(a) #利用asort函数对数组a的值排序,同时获得数组长度len
- for(i=1;i<=len;i++) print i "\t"a[i] #打印
- }'
- 1 0
- 2 1
- 3 2
- 4 8
- 5 10
- 6 100
- 7 a
- 8 b
复制代码 5. 有序输出:采用(index in array)的方式打印数组值的顺序是随机的,如果要按原序输出,则可以使用下面的方法:http://bbs2.chinaunix.net/viewthread.php?tid=1811279- awk '{a[$1]=$2
- c[j++]=$1}<br style="word-wrap: brea
收藏
举报
TAG: