我有一个文件如下
1:A
2:B
3:A
我需要的输出是:
1:A
2:B
由于第三个条目的第二列包含 A,就像第一个条目一样,因此将其删除。它还需要区分大小写。
这是一个非常大的文件,因此节省时间会很好。
我已经尝试过,但它似乎只打印独特的行
sort -u -t':' -k3,3 file
答案1
使用sort
正如埃德在他的书中所说评论,您的sort
命令是对第三个字段进行排序,而实际上您只有两个字段(这:
是字段分隔符)。因此,要修复它,请将密钥替换为3
。2
但是,当记录按其键值而不是按行/记录号排序时,源文件中的原始记录顺序会变得混乱:
$ sort -u -t':' -k2,2 test.txt
1:A
2:B
6:C
5:a
4:b
$
这可能是不是你想要什么。不过,通过再次通过管道输出可以轻松解决此问题sort
:
$ sort -u -t':' -k2,2 test.txt | sort
1:A
2:B
4:b
5:a
6:C
$
笔记:正如您所说,您有一个大文件,为了加快速度,您可能需要考虑使用--parallel
标志1:
sort --parallel=<n> -u -t':' -k2,2 test.txt | sort --parallel=<n>
您何时<n>
拥有可用的核心数。
使用awk
扩展示例文件,如果原始数据位于名为 的文件中test.txt
,如下所示:
1:A
2:B
3:A
4:b
5:a
6:C
并且,再次将 视为:
字段分隔符,那么您可以使用awk
2。
例如这一行:
awk 'BEGIN{FS=":"}{if (!seen[$2]++)print $0}' test.txt
给出以下结果:
$ awk 'BEGIN{FS=":"}{if (!seen[$2]++)print $0}' test.txt
1:A
2:B
4:b
5:a
6:C
$
您可以通过查看逻辑来了解其工作原理,使用
$ awk 'BEGIN{FS=":"}{print !seen[$2]++}' test.txt
1
1
0
1
1
1
$
- 首先,字段分隔符用 指定
FS=":"
。 - 其次,否定运算符为第二个字段条目提供“真”结果,而该结果尚未然而被看见了。
- 最后,
print $0
打印整个记录,即当前行。
将其放入 shell 脚本3而不是awk
脚本中会得到:
#!/bin/sh
awk -F':' '
(!seen[$2]++) {
print $0
}
' "$1"
参考: