如何获得Linux中两个文件之间的差异(仅添加)


72

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

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

请提出一种方法。


文件A2中所有添加的行都是新的吗?我的意思是与现有行没有重复吗?
肯特

Answers:


63

diff然后grep针对您想要的编辑类型。

diff -u A1 A2 | grep -E "^\+"

4
这将使您离开+该行的开头
kgadek '16

9
您可以使用sed删除它们:diff -u A1 A2 | grep '^\+' | sed -E 's/^\+//'
哈维尔·帕拉

@AmauryD,您的编辑将删除第一+++ A2行,但+在每行的开头都留一个符号,这就是上面的comment和sed命令所要处理的内容。
remram

2
您可以将grepand组合sed在一个命令中:diff -u A1 A2 | sed -n '/^+[^+]/ s/^+//p'
remram

缺点:此解决方案留下了引用行号的行,例如@@ -31,6 +630,8 @@
JellicleCat

82

以下所有内容均直接从@TomOnTime的serverfault答案此处复制:

显示仅存在于文件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)

5
由于我们在bash这里讨论的是,最后一个命令可以简化为comm -12 <(sort < a) <(sort < b)使用进程替换。
phk

2
先生,您是我的英雄。
Henri-Maxime Ducoulombier

52

你可以试试这个

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

       [...]

4
您能解释一下这些选项吗,我无法从手册页中获取它们
user1004985 2013年

2
有关更多gnu线组格式的信息
请参见此

1
''--unchanged-group-format=''看起来像一个单一的",这是行不通的。也许更改''""免有人输入您的答案"
lolololol ol '18

6
这是一个比所选答案好得多的答案。给您确切所需的内容,而不是乱七八糟的+符号和不必要的元行。
lolololol ol

对我来说,这还显示了已更改的行,而不仅仅是全新的行。
Florian Brucker

8

您可以输入:

grep -v -f A1 A2

假设文件A1包含一行x,文件A2包含一行x,另一行xx。此命令不输出任何内容,因为中的两行都A2包含x
timrau

2
grep-x--line-regexp)可用于确保整个行都匹配。因此,如果A1包含x且A2包含xx,将找不到匹配项。
生锈的狐猴

2
您可能还需要使用选项-F--fixed-strings。否则grep将被解释A1为正则表达式。因此,如果A1包含line .*,它将匹配所有内容。因此整个命令将是:grep -vxF -f A1 A2
wisbucky

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而无法选择。


最佳答案 !这恰好返回已添加的行,仅此而已。我认为这应该是公认的答案
Bancarel Valentin


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.