了解如何在不排序或更改其顺序的情况下使用awk'!visited $ 0 ++'。
假设您有一个文本文件,并且需要删除它的所有重复行。
要删除重复的行,同时保留它们在文件中的顺序,请使用:
awk '!visited[$0]++' your_file > deduplicated_file
该脚本会保留一个关联数组,其索引等于文件的唯一行,而值等于它们的出现次数。 对于文件的每一行,如果行出现次数为零,则将其增加一并打印该行,否则,它仅增加出现次数而无需打印该行。
我对awk并不熟悉,所以我想了解它是如何通过这么短的脚本来实现这一点的。我做了研究发现以下几点:
综上所述,整个表达式的计算结果是:
awk语句由一个模式-表达式和一个关联的操作组成 。
< pattern / expression > { < action > }
如果模式正确,则执行相关的操作。 如果我们不提供操作,awk 默认情况下会打印输入。省略操作等价于{ print $0}。
我们的脚本由一个 awk 语句和一个表达式组成,省略了操作。 所以这样:
awk '!visited[$0]++' your_file > deduplicated_file
等同于:
awk '!visited[$0]++ { print $0 }' your_file > deduplicated_file
对于文件的每一行,如果表达式成功,则将该行打印到输出。否则,不执行操作,也不打印任何内容。
uniq命令仅除去相邻的重复行 。 下面是例子:
$ cat test.txt
A
A
A
B
B
B
A
A
C
C
C
B
B
A
$ uniq < test.txt
A
B
A
C
B
A
我们还可以使用下面的 sort 命令来删除重复的行,但不保留行顺序。
sort -u your_file > sorted_deduplicated_file
前面的方法将生成一个去重复的文件,其行将根据内容进行排序。 利用管道符连接一堆命令可以解决这个问题:
cat -n your_file | sort -uk2 | sort -nk1 | cut -f2-
假设我们有以下文件:
abc
ghi
abc
def
xyz
def
ghi
klm
“cat -n test.txt”在每行前添加序号。
1 abc
2 ghi
3 abc
4 def
5 xyz
6 def
7 ghi
8 klm
sort -uk2根据第二列对行进行排序 ( k2选项),并且只保留第一次出现的具有相同第二列值的行(u 选项)。
1 abc
4 def
2 ghi
8 klm
5 xyz
Sort-nk1根据行的第一列(k1选项)对行进行排序,并将该列视为数字(- n 选项)。
1 abc
2 ghi
4 def
5 xyz
8 klm
最后,cut-f2从第二列开始打印到结束(-f2-选项: 注意-后缀,指示其包括其余的行)。
abc
ghi
def
xyz
klm
参考资料
最后是可爱的猫咪。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。