94

我有两个文件 A1 和 A2(未排序)。A1 是 A2 的早期版本,并且在 A2 中添加了一些行。如何获取添加到 A2 的新行?

注意:我只想添加新行,而不想要 A1 中但在 A2 中删除的行。当我这样做时diff A1 A2,我得到了添加和删除,但我只想要添加。

请提出一种方法来做到这一点。

4

7 回答 7

109

以下大部分内容是直接从@TomOnTime 的服务器故障答案复制而来。底部是对未排序文件的尝试,但该命令在给出差异之前对文件进行排序,因此在许多情况下它不会是所需的。对于未排序文件的格式良好的差异,您可能会发现其他答案更有用(感谢@Fritz 指出这一点):

显示仅存在于文件 a 中的行:(即从 a 中删除的内容)

comm -23 a b

显示仅存在于文件 b 中的行:(即添加到 b 中的内容)

comm -13 a b

显示仅存在于一个文件或另一个文件中的行:(但不能同时存在)

comm -3 a b | sed 's/^\t//'

(警告:如果文件a有以 TAB 开头的行,它(第一个 TAB)将从输出中删除。)

注意:这两个文件都需要进行排序,以便“comm”正常工作。如果它们尚未排序,您应该对它们进行排序:

sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted

如果文件非常长,这可能是一个相当大的负担,因为它需要额外的副本,因此需要两倍的磁盘空间。

编辑:请注意,可以使用进程替换更简洁地编写命令(感谢@phk 的评论):

comm -12 <(sort < a) <(sort < b)
于 2016-02-26T05:11:07.740 回答
74

diff然后grep是你想要的编辑类型。

diff -u A1 A2 | grep -E "^\+"
于 2013-03-13T12:07:54.157 回答
60

你可以试试这个

diff --changed-group-format='%>' --unchanged-group-format='' A1 A2

这些选项记录在man diff

       --GTYPE-group-format=GFMT
              format GTYPE input groups with GFMT

和:

       LTYPE is 'old', 'new', or 'unchanged'.
              GTYPE is LTYPE or 'changed'.

和:

              GFMT (only) may contain:

       %<     lines from FILE1

       %>     lines from FILE2

       [...]
于 2013-03-13T12:16:50.260 回答
9

与https://stackoverflow.com/a/15385080/337172类似的方法,但希望更易于理解且易于调整:

diff \
  --new-line-format="%L" \
  --old-line-format="" \
  --unchanged-line-format="" \
  A1 A2
于 2018-08-06T16:52:34.803 回答
7

简单的方法是使用:

sdiff A1 A2

另一种方法是使用comm,正如您在Comparing two unsorted lists in linux 中看到的那样,在第二个文件中列出唯一的

于 2013-03-13T12:09:26.877 回答
7

您可以键入:

grep -v -f A1 A2
于 2013-03-13T12:11:25.947 回答
6
git diff path/file.css | grep -E "^\+" | grep -v '+++ b/' | cut -c 2-
  • grep -E "^\+"来自以前接受的答案,它是不完整的,因为留下了非来源的东西
  • grep -v '+++ b'删除具有更高版本文件名的非源行
  • cut -c 2-删除+标志列,也可以使用sed 's/^\+//'

comm或者sdiff因为 git 而不是一个选项。

于 2016-11-21T10:57:01.593 回答