我有大量数据,其中每条(数据)行都应该是唯一的。
一个文件夹中有很多文件,这已经是事实。它大约有 15GB 大小,分为大约 170 个文件,共 1000000 行。我们将该文件夹称为foo
。
现在,第二个文件夹 ( bar
) 包含更多数据:每个文件中没有多个条目。两个文件的交集bar
不一定为空。那里的每个文件大约有 15k 行(并且 中有几千个文件bar
)。
现在我正在使用
awk 'NR==FNR{a[$0]=$0;next}!a[$0]' foo/file bar/file > tmp
mv tmp bar/file
以及对 中的所有文件进行循环foo
以及对 中的所有文件进行循环bar
。foo
如果为空,我就会打破循环bar/file
。我通过锁定(在多个节点上使用)和并行执行(在每个节点上)来并行化它。但这仍然需要很长的时间。
提高绩效的可能性有哪些?中的文件的理想文件大小是多少foo
?当然,这取决于机器(RAM/CPU/存储),但是这里有什么好的经验法则呢?
太长了;博士:foo
包含唯一的数据行,包含可以在和bar
中多次出现的数据行。消除重复项,以便它们可以合并bar
foo
bar
foo
[更新]没有空行[/更新]
答案1
我不确定我是否理解你的问题,但你的代码可以优化为:
awk '!x{a[$0];next}; !($0 in a)' foo/file x=1 bar/file > tmp
(我认为你的空行或解析为“0”的行有问题)
如果文件已排序,您可以执行以下操作:
comm -13 foo/file bar/file > tmp
如果不是(ksh93.zsh 或 bash 语法):
comm -13 <(sort foo/file) <(sort bar/file) > tmp
(不一定比 awk 解决方案更快)
另外,特别是对于 GNU awk,您可以通过将语言环境设置为 C/POSIX 来获得更好的性能:
LC_ALL=C awk ...
答案2
我有多个文件,每个文件的大小只有几个 MB,我已经尝试过这个对我有用:
sort *.csv | uniq -d
这将为您提供文件中的重复记录,然后您可以将输出重定向到单个文件以获取重复记录,删除-d
将为您提供所有唯一记录。