bash,Linux:设置两个文本文件之间的差异

Ada*_*tan 64 bash file-io set-difference

我有两个文件A- nodes_to_deleteB- nodes_to_keep.每个文件都有许多带有数字ID的行.

我想要列出数字ID,nodes_to_delete但不在其中nodes_to_keep,例如alt文本http://mathworld.wolfram.com/images/equations/SetDifference/Inline1.gif.

在PostgreSQL数据库中执行它是非常慢的.使用Linux CLI工具在ba​​sh中做任何简洁的方法吗?

更新:这似乎是一个Pythonic工作,但文件真的非常大.我已经解决了使用一些类似的问题uniq,sort一些集理论技术和.这比数据库等价物快两到三个数量级.

msw*_*msw 101

通讯命令做到这一点.

  • 如果文件尚未排序,请先排序`sort`. (9认同)
  • @Just不会在这里开始一场火焰战,但你的评论只是粗鲁. (7认同)
  • @Adam Matan:在`ls/bin/usr/bin |中提供更多启示 xargs man` (6认同)
  • @Adam Matan:对不起,粗鲁绝对不是我的意图.事实上,我发布的命令是学习系统的一个很好的方法,我曾经做过这样的事情来启发自己.否则,例如`join(1)`对我来说是未知的. (4认同)
  • @Adam:具有讽刺意味的是,那个"comm"位的arcana可以追溯到你可以保留/ bin和/ usr/bin的全部内容,在所有这些花哨的perls和pythons和mysql之前.回到那些更简单的V7日,你必须使用所有的工具或者(喘气!)用ed(1)编写你自己的,在雪地里,上坡两种方式,我们喜欢它!;)如果我以后开始,我可能永远不会知道通讯. (3认同)
  • +1开明,伟大的工具,我觉得愚蠢不知道.谢谢! (2认同)
  • 由于这是公认的答案,您能否包含执行 OP 要求的命令行,例如下面的@activedecay? (2认同)

sli*_*nkp 40

几个月前有人告诉我如何做到这一点,然后我找不到它一段时间......虽然看着我偶然发现了你的问题.这里是 :

set_union () {
   sort $1 $2 | uniq
}

set_difference () {
   sort $1 $2 $2 | uniq -u
}

set_symmetric_difference() {
   sort $1 $2 | uniq -u
}
Run Code Online (Sandbox Code Playgroud)

  • `set_difference`和`set_symmetric_difference`并不总能正常工作 - 如果这些行在该文件中不是唯一的,它们将删除第一个输入文件唯一的行. (4认同)
  • 这是对称差异,而不是正常的设定差异. (3认同)
  • 我认为这比接受的答案更好...... ``comm`` 并非在所有环境中都可用。 (2认同)
  • @Tgr,如果每个文件被读取一次,但第二个文件被读取两次,我的答案将给出对称差异,因此输出只是第一个文件特有的行。 (2认同)

act*_*cay 7

使用comm-它将逐行比较两个排序的文件。

您问题的简短答案

此命令将返回deleteNodes独有的行,但不返回keepNodes中的行。

comm -1 -3 <(sort keepNodes) <(sort deleteNodes)
Run Code Online (Sandbox Code Playgroud)

设置示例

让我们创建名为keepNodes和的文件deleteNodes,并将其用作comm命令的未排序输入。

$ cat > keepNodes <(echo bob; echo amber;)
$ cat > deleteNodes <(echo bob; echo ann;)
Run Code Online (Sandbox Code Playgroud)

默认情况下,运行不带参数的comm将使用以下布局打印3列:

lines_unique_to_FILE1
    lines_unique_to_FILE2
        lines_which_appear_in_both
Run Code Online (Sandbox Code Playgroud)

使用上面的示例文件,运行不带参数的comm。请注意三列。

$ comm <(sort keepNodes) <(sort deleteNodes)
amber
    ann
        bob
Run Code Online (Sandbox Code Playgroud)

抑制列输出

用-N抑制第1、2或3列;请注意,隐藏列时,空格会缩小。

$ comm -1 <(sort keepNodes) <(sort deleteNodes)
ann
    bob
$ comm -2 <(sort keepNodes) <(sort deleteNodes)
amber
    bob
$ comm -3 <(sort keepNodes) <(sort deleteNodes)
amber
    ann
$ comm -1 -3 <(sort keepNodes) <(sort deleteNodes)
ann
$ comm -2 -3 <(sort keepNodes) <(sort deleteNodes)
amber
$ comm -1 -2 <(sort keepNodes) <(sort deleteNodes)
bob
Run Code Online (Sandbox Code Playgroud)

排序很重要!

如果执行comm时未先对文件进行排序,则它会优雅地失败,并显示一条消息,提示未排序文件。

comm: file 1 is not in sorted order


Joh*_*n B 5

comm是专门为这种用例设计的,但它需要排序的输入。

awk可以说是一个更好的工具,因为它相当直接地找到集合差异,不需要sort,并且提供了额外的灵活性。

awk 'NR == FNR { a[$0]; next } !($0 in a)' nodes_to_keep nodes_to_delete
Run Code Online (Sandbox Code Playgroud)

例如,也许您只想找到表示非负数的行中的差异:

awk -v r='^[0-9]+$' 'NR == FNR && $0 ~ r {
    a[$0]
    next
} $0 ~ r && !($0 in a)' nodes_to_keep nodes_to_delete
Run Code Online (Sandbox Code Playgroud)