#1 楼
尝试comm另一种查看方式:
显示仅存在于文件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
如果文件过长,则可能会很麻烦,因为它需要额外的副本,因此需要两倍的磁盘空间。 br />
评论
只是想补充一下,此解决方案需要正确排序两个文件(区分大小写)才能产生正确的结果
– marmor
2014年4月28日上午10:29
在足够现代的外壳上,您可以使用comm -12 <(sort a)<(sort b)
–约书亚·胡贝尔(Joshua Huber)
17年2月23日在21:53
哇,一个新的linux命令,谢谢。那不再发生了。
–马特·亚历山大(Matt Alexander)
20/07/29在23:34
comm首次出现在1973年发布的AT&T UNIX版本4中。该版本Unix的其他显着特征是它是用C而不是汇编语言编写的,这使它易于移植,并极大地扩展了Unix传播的潜力。
– TomToTime
20年7月31日在17:23
#2 楼
comm
可能会做您想要的。从其手册页:Description
逐行比较排序的文件FILE1和FILE2。
如果没有选项,则产生三个-列输出。第一列
包含FILE1唯一的行,第二列
包含FILE2唯一的行,
,第三列包含两个文件的通用行
。
这些列可以分别用
-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
如手册页所述,必须事先对文件进行排序。
#3 楼
要显示没有上下文的添加和删除,请使用行号,+,-,<,>!等等,您可以像这样使用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
#4 楼
视觉比较工具将两个文件放在一起,因此具有相同行数但内容不同的段将被视为已更改的段。完全匹配的段之间的新行被视为添加的段。这也是sdiff命令行工具的工作原理,它显示了终端中两个文件的并排比较。换行用|分隔。字符。如果仅在文件A中存在一行,则将<用作分隔符。如果仅在文件B中存在一行,则将>用作分隔符。如果文件中没有<和>字符,则可以使用此字符仅显示添加的行:
sdiff A B | grep '[<>]'
评论
sdiff --suppress-common-lines可能是人们所需要的;它包括|以及>行,但这正是我所需要的。
–dimo414
20-04-29在21:36
#5 楼
这就是diff在默认情况下所做的...也许您需要添加一些标志以忽略空格?diff -b -B
应忽略空行和不同数量的空格。
评论
不,它还显示CHANGED行(具有一个字符或四个不同的行)。我想要仅存在于左侧或右侧的线。
– C.罗斯
09-09-25 13:35
您可能会争辩说,CHANGED文件的不同版本仅存在于左侧或右侧。
– markdrayton
09-09-25 14:28
diff(或任何其他工具)无法可靠地告知更改内容以及删除的行被新行替换。
–钱
09年9月25日在15:07
从技术上讲,diff将“更改的”行视为删除了原始行并添加了新行...因此从技术上讲,它仅显示已添加和删除的行。
– KFro
09年9月25日在17:33
#6 楼
不,diff
实际上并未以人们可能认为的方式显示出两个文件之间的差异。它为patch
之类的工具生成一系列编辑命令,以用于将一个文件转换为另一个文件。 任何尝试做您想做的事情的难点是如何定义构成变化的线与删除的线和添加的线的关系。另外,当行彼此相邻添加,删除和更改时,该怎么办。
评论
我的想法正好。为了将其视为新字符而不是对原始字符的修改,必须更改一行字符的百分比?从技术上讲,即使您有一个共同的字符,也可以将其视为“更改”,而不是删除和插入。
–卡米尔·基西尔(Kamil Kisiel)
09年9月25日在18:35
自从查看差异源以来已经有很长时间了,但是我似乎还记得各种旋转方式来跟踪两个文件的匹配位置以保持同步,并且我认为基于相互之间的距离有一个放弃的阈值线是。但是我不记得任何行内匹配,除了(可选)折叠的空白或忽略大小写。或(也许)话语影响。无论如何,都是关于补丁的,而“ vgrep”就随它而来。也许。星期二。
–丹尼斯·威廉姆森
09-09-25 at 18:54
#7 楼
感谢senarvi,您的解决方案(未经投票)实际上是给我找了一堆页面上的年龄之后想要的。使用您的答案,这是我想出的清单更改/添加/删除的内容。该示例使用/ etc / passwd文件的2个版本,并打印出相关记录的用户名。
#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " }'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " }'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print }' | awk -F: '{print "added: " }'
评论
注意,因为“已修改一行”和“已删除一行并在其下方或上方添加了另一行”之间的区别是语义上的。基于通用文本的差异工具无法区分这些情况。结果,您基于sdiff的答案不能在所有情况下都可靠地起作用。
– Mikko Rantalainen
17-2-21在13:44
#8 楼
我发现这种特殊形式经常有用: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中进行了测试。 />
#9 楼
文件1:text670_1
text067_1
text067_2
文件2:
text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1
使用:
diff -y file1 file2
这显示了对应文件的两列。
输出:
text670_1
> text04_1
> text04_2
> text05_1
> text05_2
text067_1 text67_1
text067_2 text67_2
> text1000_1
评论
您需要更好地定义添加和删除的含义。具体来说,线可以改变吗?如果是这样,您如何处理更改的行?如果执行严格的面向行的检查,则更改的行与要删除的旧行和要添加的新行相同。例如,它应该如何处理一分为二的行?由于两个1线改变了? 2行改了吗?删除1行并添加2行?除非您能保证行永远不会改变,而只是添加和删除,否则我认为如果没有更好的定义,这注定会失败。我觉得这个问题还不清楚。但是至少可以用diff A B |回答这个问题。 grep'^ [<>]'
您可能正在寻找com。
@ChristopherCashell,他的意思是忽略排序顺序;一个典型的常见问题。通常,这是通过在进行典型差异之前首先对每侧的线段(线)进行排序来实现的。
@Pacerier,您确定吗?还是在猜?问题中未提及或暗示任何有关排序或搜索顺序的信息。就目前而言,这个问题尚不清楚,可以用许多不同的方式来解释。在不确定是否要问他在问什么的情况下,我们正在做假设并提供可能会或可能不会解决实际问题的解决方案。此外,原始海报对答案之一的评论表明,这与排序无关。它确实与“添加和删除”与“更改”的含义有关。