awk '!a[$0]++'去重小技巧

今天碰到一个关于awk的去重用法,觉得挺有意思的,记录一下

awk 按行去重

awk '!a[$0]++' file 是个神奇的用法,通过它可以实现文件内容去重

  • $0: 代表整行
  • a[]: 代表数组a,名称随意,首次调用时为空
  • ++: 与C/C++中的++一个含义,i++先使用i后i自增1,++i代表i先自增1然后被使用
  • !: 代表取反

所以a[$0]代表对当前行构建一个名为a的数组,首次构建后其值为0

a[$0]++代表先使用a[$0]的值,然后a[$0]的值自增1。首次调用自然就是0,下次遇到重复的行就变为1,所以不加!的情况下,该语法用于打印重复项,看下面的例子↓

$ cat test
aaa
bbb
aaa
ccc
bbb
aaa
ddd
bbb
$ awk 'a[$0]++' test
aaa
bbb
aaa
bbb

它把文件中重复的行都打印出来了。为了去重,我们只需在前面加个取反符!即可,这便是!a[$0]++

$ awk '!a[$0]++' test
aaa
bbb
ccc
ddd

awk 按列去重

上面使用$0构建数组,如果我们使用第i列的值$i构建数组,使用awk '!a[$i]++' file则可以按照指定列的关键词实现去重↓

$ cat test
aaa 111
bbb 222
aaa 222
ccc 222
bbb 333
aaa 444
ddd 111
bbb 111
$ awk '!a[$2]++' test
aaa 111
bbb 222
bbb 333
aaa 444

可以看到,test文件中第2列均不重复,但是其它列允许重复。这种用法在某些特定情况下是非常实用的。