如何获取差异以仅显示添加和删除的行?如果diff无法做到,那么什么工具可以呢?
diff A B | grep '^[<>]'
comm
。
如何获取差异以仅显示添加和删除的行?如果diff无法做到,那么什么工具可以呢?
diff A B | grep '^[<>]'
comm
。
Answers:
另一种查看方式:
显示仅存在于文件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
如果文件过长,则可能会很麻烦,因为它需要额外的副本,因此需要两倍的磁盘空间。
comm -12 <(sort a) <(sort b)
comm
可能会做您想要的。从其手册页:
描述
逐行比较排序的文件FILE1和FILE2。
如果没有选项,则产生三列输出。第一列包含FILE1独有的行,第二列包含FILE2独有的行,第三列包含两个文件共同的行。
这些列是suppressable用-1
,-2
和-3
分别。
例:
[root@dev ~]# cat a
common
shared
unique
[root@dev ~]# cat b
common
individual
shared
[root@dev ~]# comm -3 a b
individual
unique
而且,如果您只想要唯一的行,而不关心它们位于哪个文件中:
[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique
如手册页所述,必须事先对文件进行排序。
要显示没有上下文的添加和删除,请使用行号+,-,<,>!等等,您可以像这样使用diff:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
例如,给定两个文件:
a.txt
Common
Common
A-ONLY
Common
b.txt
Common
B-ONLY
Common
Common
以下命令将显示从a删除或添加到b的行:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
输出:
B-ONLY
A-ONLY
这个略有不同的命令将显示从a.txt中删除的行:
diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt
输出:
A-ONLY
最后,此命令将显示添加到a.txt中的行
diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt
输出
B-ONLY
不,diff
实际上并没有以人们可能想到的方式显示两个文件之间的差异。它为工具(例如patch
用来将一个文件转换为另一个文件)产生一系列编辑命令。
任何尝试做您要寻找的问题的难点在于,如何定义构成变化的线与删除的线和添加的线的关系。另外,添加,删除和更改彼此相邻的行时该怎么办。
diff
来源以来已经有很长时间了,但是我似乎还记得各种旋转方式来跟踪两个文件的匹配位置以保持同步,并且我认为根据放弃的距离有多大的门槛线是。但是我不记得任何行内匹配,除了(可选)折叠的空白或忽略大小写。或(也许)话语影响。无论如何,这就是一切patch
,“ vgrep”就随它而来。也许。星期二。
视觉比较工具将两个文件放在一起,因此具有相同行数但内容不同的段将被视为已更改的段。匹配段之间的全新行被视为添加的段。
sdiff命令行工具也是如此,它显示了终端中两个文件的并排比较。换行用|分隔。字符。如果仅在文件A中存在一行,则将<用作分隔符。如果仅在文件B中存在一行,则将>用作分隔符。如果文件中没有<和>字符,则可以使用此字符仅显示添加的行:
sdiff A B | grep '[<>]'
感谢senarvi,您的解决方案(未经投票)实际上为我提供了我想要的东西,经过一千吨的页面寻找。
使用您的答案,这是我想出的更改/添加/删除内容的清单。该示例使用/ etc / passwd文件的2个版本,并打印出相关记录的用户名。
#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'
我发现这种特殊形式通常很有用:
diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g
例:
printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
输出:
-b
-c
+B
+C
-e
-f
+E
+F
因此它显示的是旧行,-
紧随其后的是对应的新行+
。
如果我们删除了C
:
printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
它看起来像这样:
-b
+B
+C
-e
-f
+E
+F
该格式记录在man diff
:
--line-format=LFMT
format all input lines with LFMT`
和:
LTYPE is 'old', 'new', or 'unchanged'.
GTYPE is LTYPE or 'changed'.
和:
LFMT (only) may contain:
%L contents of line
%l contents of line, excluding any trailing newline
[...]
相关问题:https : //stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux
在Ubuntu 18.04中测试。