【问题标题】:Find lines from a file which are not present in another file [duplicate]从一个文件中查找另一个文件中不存在的行[重复]
【发布时间】:2013-01-06 12:59:27
【问题描述】:

我有两个文件(比如说a.txtb.txt),它们都有一个名称列表。我已经在这两个文件上运行了sort

现在我想从a.txt 中找到b.txt 中不存在的行。

(我花了很多时间来寻找这个问题的答案,所以记录下来以备将来参考)

【问题讨论】:

    标签: unix text-files


    【解决方案1】:

    你必须使用的命令不是diff而是comm

    comm -23 a.txt b.txt
    

    默认情况下,comm 输出 3 列:left-onlyright-onlyboth-1-2-3 开关抑制这些列。

    因此,-23 隐藏了 right-onlyboth 列,显示仅出现在第一个(左侧)文件中的行。

    如果你想找到同时出现的行,你可以使用-12,它隐藏了 left-onlyright-only 列,留给你只是 both 列。

    【讨论】:

    • 我要补充一点,这只有在两个文件都已排序时才有效。 (我知道 OP 提到他对文件进行了排序,但包括我在内的很多人阅读了问题标题然后跳转到答案)
    • @user247866:幸运的是,comm 很友好地告诉你它们是否没有排序:)
    【解决方案2】:

    简单的答案对我不起作用,因为我没有意识到comm 匹配行,因此一个文件中的重复行将被打印为另一个文件中不存在。例如,如果 file1 包含:

    Alex
    Bill
    Fred
    

    文件2包含:

    Alex
    Bill
    Bill
    Bill
    Fred
    

    然后comm -13 file1 file2 会输出:

    Bill
    Bill
    

    在我的例子中,我只想知道 file2 中的每个字符串都存在于 file1 中,而不管该行在每个文件中出现了多少次。

    解决方案 1:-u(唯一)标志用于 sort

    comm -13 <(sort -u file1) <(sort -u file2)

    解决方案 2:(我找到的第一个“有效”答案)来自 unix.stackexchange

    fgrep -v -f file1 file2

    请注意,如果 file2 包含 file1 中根本不存在的重复行,fgrep 将输出每个重复行。另请注意,我在一台笔记本电脑上对单个(相当大的)数据集进行的完全非科学测试表明,解决方案 1(使用 comm)比解决方案 2(使用 fgrep)快近 5 倍。

    【讨论】:

    • 我对我的文件进行了排序并通过了 uniq。无论如何感谢其他解决方案。
    • fgrep 版本会很慢,如果你有几万行的话。
    【解决方案3】:

    我不知道为什么有人说不应该使用diff。我会用它来比较两个文件,然后只输出左侧文件中的行,而不是右侧文件中的行。此类行由带有< 的 diff 标记,因此在行的开头使用 grep 符号就足够了

    diff a.txt b.txt  | grep \^\<
    

    【讨论】:

    • 您可以使用diff --new-line-format= --unchanged-line-format= a.txt b.txt 来抑制新行和未更改行的打印。
    • diff 对我来说效果很好。我是win10,没有安装comm。
    【解决方案4】:

    如果文件还没有被排序,你可以使用:

    comm -23 <(sort a.txt) <(sort b.txt)
    

    【讨论】:

    • 这为我分配了 15GB 的内存,每个文件
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    相关资源
    最近更新 更多