有没有一种使用shell工具从列表中删除重复和冗余子字符串的方法?这里所说的“冗余”是指包含在另一个字符串中的字符串,因此“foo”与“foobar”和“barfoo”重复。
例如,考虑以下列表:
abcd
abc
abd
abcd
bcd
并返回:
abcd
abd
uniq
,sort -u
和awk '!seen[$0]++'
可以有效地去除重复的字符串,但不能去除冗余的字符串。如何在不排序文件的情况下删除文件中的重复行?删除非排序重复行
我可以使用grep
递归遍历每一行,但对于大型文件来说速度相当慢。(我需要处理大约10^8行。)这里有一种使用Python循环的方法:基于部分字符串删除冗余字符串以及Bash中的方法:如何检查一个字符串是否包含子字符串但我试图避免循环。编辑:我指的是嵌套循环,在此感谢@shellter的澄清。有没有办法使用awk的
match()
函数与数组索引一起使用?这种方法逐步构建数组,因此永远不必搜索整个文件,因此应该对大型文件更快。或者我错过了其他简单的解决方案吗?理想的解决方案将允许匹配指定的列,就像上面的方法一样。
编辑
以下两个答案都有效,非常感谢帮助。目前正在测试实际数据集的性能,将用结果更新并接受一个答案。我在相同的输入文件上测试了两种方法,该文件有430,000行,其中417,000行是非冗余的。供参考,我的原始循环grep方法对此文件需要7h30m。
更新:
James Brown的原始解决方案需3h15m,而Ed Morton的则需8h59m。在较小的数据集上,James的更新版本为7m,而原始版本为20m。谢谢你们俩,这真的很有帮助。
我正在处理大约110个字符每个字符串,通常每个文件有数以千计的行。创建这些字符串(抗体蛋白质序列)的方式可能会导致字符串的一个或两个末尾的字符丢失。因此,"bcd"很可能是"abcde"的一个片段。
ab
是否应该被视为对abcd
的冗余?那只有a
呢...嗯,或者只有b
呢?此外,请定义循环。任何读取完整文件的脚本都是一个循环,如果需要返回进行双重检查,则将是另一个循环(我不会担心这个问题,先清楚地定义和解决您的问题,然后再考虑循环;-))。祝你好运! - shellter