为什么使用忽略匹配行的diff不能按预期工作?

A K*_*A K 10 shell diff ignore

我有以下文件:

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}}
Run Code Online (Sandbox Code Playgroud)

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}}
Run Code Online (Sandbox Code Playgroud)

我正在运行以下命令:

diff -I 'Memory' file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)

哪个输出:

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}}
Run Code Online (Sandbox Code Playgroud)

但是我的预期输出是:

< Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 9030 ms}}
---
> Tab=> 'Cpu' Title=> {text {Total cumulative CPU time: 90303 ms}}
Run Code Online (Sandbox Code Playgroud)

请注意,在命令中如果我将"Memory"更改为"Tab"或"Title"问题已解决,但可能所有行都被忽略,因为它们都有Tab和Title.

Mik*_*ert 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}}
Run Code Online (Sandbox Code Playgroud)

文件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}}
Run Code Online (Sandbox Code Playgroud)

一个简单的差异会给你:

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}}
Run Code Online (Sandbox Code Playgroud)

请注意,现在有两组差异......通过这种安排,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}}
Run Code Online (Sandbox Code Playgroud)

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


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


arm*_*mel 5

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

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

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


小智 0

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

the pen is on the table
Run Code Online (Sandbox Code Playgroud)

f2 是:

the pun is on the table
Run Code Online (Sandbox Code Playgroud)

将正确解析:

diff -I 'p.n' f2 f2
Run Code Online (Sandbox Code Playgroud)

什么也不给予

如果 f2 现在变成

the pun is on the cable
Run Code Online (Sandbox Code Playgroud)

正则表达式不再匹配(电缆和表格与正则表达式不匹配...),因此您将在输出中出现两行...

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

diff -I '.*Memory.*' file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题(抱歉这些愚蠢的例子..)