15

我有以下文件:

file1.txt

###################################################
Dump stat Title information for 'ssummary' view
###################################################
Tab=> 'Instance' Title=> {text {Total instances: 7831}}
Tab=> 'Device' Title=> {text {Total spice devices: 256}}
Tab=> 'Memory' Title=> {text {Total memory allocated: 962192 kB}}
Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 9030 ms}}

file2.txt

###################################################
Dump stat Title information for 'ssummary' view
###################################################
Tab=> 'Instance' Title=> {text {Total instances: 7831}}
Tab=> 'Device' Title=> {text {Total spice devices: 256}}
Tab=> 'Memory' Title=> {text {Total memory allocated: 9621932 kB}}
Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 90303 ms}}

我正在运行以下命令:

diff -I 'Memory' file1.txt file2.txt

输出:

6,7c6,7
< Tab=> 'Memory' Title=> {text {Total memory allocated: 962192 kB}}
< Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 9030 ms}}
---
> Tab=> 'Memory' Title=> {text {Total memory allocated: 9621932 kB}}
> Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 90303 ms}}

但是我的预期输出是:

< Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 9030 ms}}
---
> Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 90303 ms}}

请注意,在命令中,如果我将“内存”更改为“标签”“标题”问题已解决,但可能所有行都被忽略,因为它们都有标签和标题。

4

5 回答 5

7

diff考虑到工作方式(截至 2013 年 4 月),这种行为是正常的。

diff是面向线的,这意味着一条线要么被认为完全不同,要么完全等同。当一行被忽略时,它在比较之前被输入到不同行的列表中,并且当计算更改脚本时,仅对被忽略行所做的更改被认为是被忽略的。当被忽略的行与更改的行相邻时,它构成一个未忽略的更改。

问题在于无法diff理解连续行不相关:您不是在区分文本序列(diff目标是什么),而是区分键控的独立行列表(Tab >= <key>)。当两个文件以相同的顺序生成时,这些问题看起来非常相似,但仍然不一样。

于 2013-04-10T10:43:15.420 回答
5

这种行为确实看起来有点奇怪。我通过调整您的输入文件注意到了一些事情(我只是将“内存”行移到两个文件的顶部):

文件1.txt

###################################################
Dump stat Title information for 'ssummary' view
###################################################
Tab=> 'Memory' Title=> {text {Total memory allocated: 962192 kB}}
Tab=> 'Instance' Title=> {text {Total instances: 7831}}
Tab=> 'Device' Title=> {text {Total spice devices: 256}}
Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 9030 ms}}

文件2.txt

###################################################
Dump stat Title information for 'ssummary' view
###################################################
Tab=> 'Memory' Title=> {text {Total memory allocated: 9621932 kB}}
Tab=> 'Instance' Title=> {text {Total instances: 7831}}
Tab=> 'Device' Title=> {text {Total spice devices: 256}}
Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 90303 ms}}

一个普通的差异会给你:

diff file1.txt file2.txt

4c4
< Tab=> 'Memory' Title=> {text {Total memory allocated: 962192 kB}}
---
> Tab=> 'Memory' Title=> {text {Total memory allocated: 9621932 kB}}
7c7
< Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 9030 ms}}
---
> Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 90303 ms}}

请注意,现在有两组差异......通过这种安排,diff -I 'Memory' file1.txt file2.txt命令起作用并输出:

7c7
< Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 9030 ms}}
---
> Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 90303 ms}}

意思是,该-I标志似乎仅在一组差异中的每一行都与表达式匹配时才起作用。我不知道这是一个错误还是预期的行为......但这肯定是不一致的。


编辑:实际上,根据GNU diff 文档,这是预期的行为。手册页不是很清楚。OpenBSD diff 也有一个-I标志,但他们的手册页解释得更好。

于 2013-04-04T10:37:53.120 回答
3

好吧,你每天都会学到新东西。我同样对这种行为感到困惑和沮丧,这似乎大致是 [diff the input files, then filter out the RE] 而不是 [filter the RE out of the input files, then diff]。

我会认为第二种方法更自然,更有用。例如,这似乎是方法--ignore-case--strip-trailing-cr工作,在差异之前调整输入文件。此外,实际实现提问者想要的内容涉及过滤临时文件的两个输入,区分它们,然后删除它们。如果你想像我一样做一个递归差异,它会变得更加乏味。

我承认 diff 的行为方式与其记录的方式不同,而不是我希望它的行为方式,但恭敬地建议这个选项(也类似 for -b-w 可以有用地添加到 diff 中。

于 2016-06-01T08:39:47.153 回答
1

这是按照diffutils手册的预期行为:

但是,如果大块中的每个更改的行(每个插入和每个删除)都与正则表达式匹配,则-I忽略包含正则表达式的行的插入或删除。

换句话说,对于每个不可忽略的更改,diff打印其附近的完整更改集,包括可忽略的更改。您可以使用多个-I选项为要忽略的行指定多个正则表达式。diff尝试将每一行与每个正则表达式匹配,从给定的最后一个开始。人差异

您可以尝试通过指定来设置较小的更改集-d,但在您的示例中它不起作用。

-d --minimal努力找到一组较小的更改。

于 2015-03-22T00:41:31.920 回答
0

从 man diff 中,如果我记得清楚的话, -I 只是忽略了其中包含的 reg exp。这意味着如果 f1 是:

the pen is on the table

f2 是:

the pun is on the table

会正确解析:

diff -I 'p.n' f2 f2

什么都不给

如果 f2 现在变成

the pun is on the cable

正则表达式不再匹配(电缆和表格与正则表达式不匹配......)所以你会在输出中出现两行......

因此,只需尝试更改以下命令:

diff -I '.*Memory.*' file1.txt file2.txt

那应该可以解决问题(对不起愚蠢的例子..)

于 2013-04-04T10:33:32.630 回答