Shell 如何计算linux上两个文件之间的差异?

Shell 如何计算linux上两个文件之间的差异?,shell,count,diff,Shell,Count,Diff,我需要处理大文件,必须找出两者之间的差异。我不需要不同的位元,只需要不同的数目 找到我计算出的不同行数 diff --suppress-common-lines --speed-large-files -y File1 File2 | wc -l 这是可行的,但有更好的方法吗 以及如何计算差异的确切数量(使用标准工具,如bash、diff、awk、sed和一些旧版本的perl) diff列表顶部的两个文件名减去2。统一格式可能比并排格式快一点。如果使用Linux/Unix,那么使用comm-1

我需要处理大文件,必须找出两者之间的差异。我不需要不同的位元,只需要不同的数目

找到我计算出的不同行数

diff --suppress-common-lines --speed-large-files -y File1 File2 | wc -l
这是可行的,但有更好的方法吗

以及如何计算差异的确切数量(使用标准工具,如bash、diff、awk、sed和一些旧版本的perl)


diff
列表顶部的两个文件名减去2。统一格式可能比并排格式快一点。

如果使用Linux/Unix,那么使用
comm-1 file1 file2
打印file1中不在file2中的行,使用
comm-1 file1 file2 | wc-l
进行计数,同样,对于通信-2…?

如果要计算不同的行数,请使用以下命令:

diff -U 0 file1 file2 | grep ^@ | wc -l

John的回答不是重复计算了不同的行吗?

由于每个不同的输出行都以
字符开头,我建议:

diff file1 file2 | grep ^[\>\<] | wc -l

diff file1 file2 | grep^[\>\如果您处理的文件内容类似,应按行对行进行排序(如描述类似内容的CSV文件),并且您希望在以下文件中找到两个差异:

File a:    File b:
min,max    min,max
1,5        2,5
3,4        3,4
-2,10      -1,1
您可以在Python中实现它,如下所示:

different_lines = 0
with open(file1) as a, open(file2) as b:
    for line in a:
        other_line = b.readline()
        if line != other_line:
            different_lines += 1

我认为正确的解决办法是:

$ diff -y --suppress-common-lines a b | grep '^' | wc -l
1

下面是一种计算两个文件之间任何类型差异的方法,为这些差异指定正则表达式-此处
为除换行符以外的任何字符:

git diff --patience --word-diff=porcelain --word-diff-regex=. file1 file2 | pcre2grep -M "^@[\s\S]*" | pcre2grep -M --file-offsets "(^-.*\n)(^\+.*\n)?|(^\+.*\n)" | wc -l
摘自
mangitdiff

——耐心
使用“耐心差异”算法生成差异。
--单词diff[=]
显示单词diff,使用来分隔更改的单词。默认情况下,单词由空格分隔;请参阅下面的--word diff regex。
瓷器
使用用于脚本使用的基于行的特殊格式。添加/删除/未更改的运行以通常的统一格式打印
格式,从行首的+/-/``字符开始,一直延伸到行尾。输入中的换行符
由其自身线条上的波浪线表示。
--单词diff正则表达式=
用于确定一个单词是什么,而不是将一系列非空白视为一个单词。也意味着--word diff,除非
已启用。
的每个非重叠匹配项都被视为一个单词。这些匹配项之间的任何内容都被视为空白并被忽略(!)
用于查找差异。您可能希望将|[^[:space:]附加到正则表达式以确保其匹配
所有非空白字符。包含换行符的匹配项在换行符处被自动截断(!)。
例如,-word diff regex=。将每个字符视为一个单词,并相应地逐字符显示差异。

pcre2grep
是Ubuntu 20.04上的
pcre2 utils
软件包的一部分。

这不起作用,因为我定义“工作”,每个文件中只有一个字符,数字“4”与什么有关?这确实起作用。对于您的示例,您有四行:前两行是每个文件的名称(如答案所述)另外两个是两个差异,1行加上“A”,1行加上“B”。这取决于你如何计算差异。在这个例子中,我认为有2条不同的线,即我同意红杉麦克道威尔。从结果中减去2也很不方便(因为2个DIF:ED文件的打印)。.因此,我认为Josh的答案是正确的。使用–c(count)可以稍微缩短答案grep上的选项,而不是管道到wc-l,比如:
diff-U 0 file1 file2 | grep-c^@
diff-U 0 file1 file2 | grep-v^ | tail-n+3 | wc-l
应该给出正确的计数。它排除了diff输出顶部的文件名。正确的解决方案正如sureshw在另一个答案中指出的那样,
comm
希望它的参数是经过排序的文件。因此,这个建议只能在特殊情况下使用。(我认为使用awk编写自己的
comm
版本很容易,因为它也适用于未排序的输入,但我怀疑这是否满足了原始问题的精神。)是的,它是双重计数。请参阅我对已接受答案的评论。此答案中的命令是正确的。在MacOSX和Ubuntu上,这对我来说可能也是双重计数行。连续行的批可以在单个块中组合在一起,这取决于您的任务,这应该是一个差异还是几个差异l、 正如@khedron指出的,成批的连续行可以在一个块中组合在一起。据我估计,这意味着这种方法容易计算不足。你可以编写
grep-c^@
,而不是
grep^@;wc-l
“容易计算不足”在两个完全不同的文件上运行这个命令,它会给你一个结果1。这会加倍计算行数,因为可以为同一行打印“”。问题中哪里说他想计算行数差异,而不是字符差异?我看到的是“位”和“精确差异数”,而是“行数”只是他想这么做。。
git diff --patience --word-diff=porcelain --word-diff-regex=. file1 file2 | pcre2grep -M "^@[\s\S]*" | pcre2grep -M --file-offsets "(^-.*\n)(^\+.*\n)?|(^\+.*\n)" | wc -l
--patience
           Generate a diff using the "patience diff" algorithm.
--word-diff[=<mode>]
           Show a word diff, using the <mode> to delimit changed words. By default, words are delimited by whitespace; see --word-diff-regex below.
           porcelain
               Use a special line-based format intended for script consumption. Added/removed/unchanged runs are printed in the usual unified diff
               format, starting with a +/-/` ` character at the beginning of the line and extending to the end of the line. Newlines in the input
               are represented by a tilde ~ on a line of its own.
--word-diff-regex=<regex>
           Use <regex> to decide what a word is, instead of considering runs of non-whitespace to be a word. Also implies --word-diff unless it
           was already enabled.
           Every non-overlapping match of the <regex> is considered a word. Anything between these matches is considered whitespace and ignored(!)
           for the purposes of finding differences. You may want to append |[^[:space:]] to your regular expression to make sure that it matches
           all non-whitespace characters. A match that contains a newline is silently truncated(!) at the newline.
           For example, --word-diff-regex=.  will treat each character as a word and, correspondingly, show differences character by character.