bash,Linux:设置两个文本文件的区别

我有两个文件Anodes_to_deleteBnodes_to_keep 。 每个文件都有许多带有数字ID的行。

我想拥有nodes_to_delete中的数字id的列表,但不包含在nodes_to_keep ,例如alt text http://mathworld.wolfram.comhttp://img.dovov.comequations/SetDifference/Inline1.gif 。

在PostgreSQL数据库中执行它是不合理的。 任何使用Linux CLI工具在ba​​sh中完成的方式?

更新:这似乎是一个Pythonic的工作,但文件是真的,真的很大。 我用uniqsort和一些理论技巧解决了一些类似的问题。 这比数据库等效的速度要快两到三个数量级。

comm命令做到这一点。

几个月前,有人向我展示了如何做到这一点,然后我找不到一段时间……而看着我偶然发现你的问题。 这里是 :

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

我脑海中的第一件事是:

 diff nodes_to_delete nodes_to_keep | grep '<' 

我在编辑之前已经回答了,所以我不认为这可能仍然适用,如果你发现数据库的方式是慢的…

也许你需要一个更好的方式来做到这一点在postgres,我敢打赌,你不会find一个更快的方式来使用平面文件。 你应该能够做一个简单的内部连接,并假设这两个id cols索引应该是非常快的。

使用comm – 它将逐行比较两个sorting的文件

以下是使用此示例设置的OP问题的答案。 这个命令将返回deleteNodes的唯一行,不在keepNodes中

 comm -1 -3 <(sort keepNodes) <(sort deleteNodes) 

解释:显示deleteNodes的唯一行,隐藏其他行


示例设置

我们将使用keepNodes和deleteNodes。 它们被用作未sorting的input。

 $ cat > keepNodes <(echo bob; echo amber;) $ cat > deleteNodes <(echo bob; echo ann;) 

默认情况下没有参数,通讯打印3列

 unique_to_FILE1 unique_to_FILE2 lines_appear_in_both 

这是没有参数的comm一个准系统例子。 注意三列。

 $ comm <(sort keepNodes) <(sort deleteNodes) amber ann bob 

抑制列输出

用-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 

当您忘记sorting时,它会优雅地失败

comm: file 1 is not in sorted order

comm是专门为这种用例devise的,但它需要分类input。

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

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

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

 awk -vr='^[0-9]+$' 'NR == FNR && $0 ~ r { a[$0] next } $0 ~ r && !($0 in a)' nodes_to_keep nodes_to_delete