我有多个这样的文件:
file1:
item1
item2
item3
file2:
item1
item5
item3
file3:
item2
item1
item4
我想要一个包含所有独特元素的文件。我可以用Python做到这一点,唯一的问题是每个文件包含不同的百万行,我想知道是否有更好的方法(可能只使用shell脚本?)。
答案 0 :(得分:4)
怎么样:
cat * | uniq
如果每个文件本身包含重复,则可能会提高效率:
for file in *; do cat $file | uniq; done | uniq
如果它们不是排序文件,uniq不起作用,所以这可能不会更有效,因为您需要:
for file in *; do sort $file | uniq; done | sort | uniq
答案 1 :(得分:2)
如果您想要所有三个文件之间的共同元素,另一种方法是使用一些grep
操作:
$ grep -F -f file1 file2 > file1inFile2
$ grep -F -f file1 file3 > file1inFile3
$ grep -F -f file1inFile2 file1inFile3 > elementsInCommon
-f
选项指定搜索模式文件(在这种情况下为file1
和file1inFile2
)。 -F
选项执行固定字符串搜索。
如果你使用bash
,你可以做一个花哨的单行:
$ grep -F -f <(grep -F -f file1 file2) <(grep -F -f file1 file3) > elementsInCommon
我认为,Grep在次线性时间搜索。因此,这可能会解决使用sort|uniq
方法预分析非常大的文件的常规 O(n log n)时间成本。
您可以进一步加快固定字符串grep
操作,specifying LC_ALL=C
环境变量。但是,当我探索这个时,它似乎是一个shell默认值。尽管如此,考虑到报告的时间改进,如果您使用grep
,此设置似乎值得研究。
但是,如果输入已经排序,则可以一次一行地遍历每个文件,测试三行之间的字符串相等性。然后,您可以将一些输入文件指针向前移动一行,或者打印三个输入共有的相等字符串。这种方法使用 O(n)时间(你遍历每个文件一次)和 O(1)内存(缓冲三行)。更多的时间,但更少的记忆。不确定是否可以使用bash
内置函数或核心实用程序来完成,但这绝对可以用于Python,Perl,C等。