【问题标题】:How to find which line is missing in another file如何查找另一个文件中缺少哪一行
【发布时间】:2014-02-06 23:03:43
【问题描述】:

在 Linux 机器上 我有一个文件如下 A.txt

1
2
3
4

第二个文件如下 B.txt

1
2
3
6

我想知道 A.txt 里面有什么,但 B.txt 里面没有 即它应该打印值 4

我想在 Linux 上这样做。

【问题讨论】:

  • 不知道为什么这被认为是“不清楚” - comm 是您正在寻找的命令。在这种特定情况下comm -23 A.txt B.txt.
  • 似乎“不清楚”被用于缺乏“不努力”的接近。
  • 这是一个很好的问题 - 它以一种我可以在谷歌上轻松找到的方式描述了我的确切问题,并且它有我可以使用的答案。

标签: linux sed awk grep


【解决方案1】:
awk 'NR==FNR{a[$0]=1;next}!a[$0]' B A

没试过,试试看

【讨论】:

  • 这将使用两个文件中的值的超集填充a[],因此会占用不必要的内存。最好改为使用awk 'NR==FNR{a[$0];next} !($0 in a)' B A,这样它只需将B 的内容保存在内存中。
【解决方案2】:

如果文件按照示例输入所示排序,请使用 comm:

$ comm -23 A.txt B.txt
4

如果文件未排序,请参阅@Kent 的 awk 解决方案。

【讨论】:

  • 谢谢!这正是我们想要的!
  • 我认为这应该被标记为实际答案!
【解决方案3】:

您也可以通过组合-v(显示不匹配的行)、-x(匹配整行)和-f(从文件中读取模式)选项来使用 grep:

$ grep -v -x -f B.txt A.txt
4

这不依赖于文件的顺序 - 它会从 A 中删除与 B 中的行匹配的所有行。

【讨论】:

  • 太棒了!像魅力一样工作,甚至不需要对行进行排序。谢谢。
【解决方案4】:

(对@rjmunro 的回答的补充)

为此使用grep 的正确方法是:

$ grep -F -v -x -f B.txt A.txt
4

如果没有-F 标志,grep 将从B.txt 读取的 PATTERN 解释为基本正则表达式 (BRE),这在此处是不受欢迎的,并且可能会导致麻烦。 -F 标志使 grep 将 PATTERN 视为一组换行符分隔的字符串。例如:

$ cat A.txt
&
^
[
]

$ cat B.txt
[
^
]
|

$ grep -v -x -f B.txt A.txt
grep: B.txt:1: Invalid regular expression

$ grep -F -v -x -f B.txt A.txt
&

【讨论】:

  • 这显然是最好的答案。它可以写成更紧凑的grep -Fvx -f B.txt A.txt
【解决方案5】:

使用差异:

diff --changed-group-format='%<' --unchanged-group-format='' A.txt B.txt

【讨论】:

  • 我不确定diff 是否能解决这个问题。想想在 A 中,我有 1-10,但在 B 中,我有 9-1 和 100-200。都是未排序的。输出应该是 10。
  • 关于文件排序的问题。它不适用于未排序的文件。您可以使用 sort 或任何其他 shell 命令对文件进行排序。
猜你喜欢
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-26
  • 1970-01-01
相关资源
最近更新 更多