2013-04-04 7 views
6

Ich habe die folgenden Dateien:Warum funktioniert das Vergleichen von Zeilen nicht wie erwartet?

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}} 

Und ich bin den folgenden Befehl ausführen:

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

die Ausgänge :

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}} 

jedoch meine erwartete Ausgabe ist:

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

Beachten Sie, dass in dem Befehl, wenn ich ‚Memory‘ auf ‚Tab‘ oder ‚Titel‘ Problem ist gelöst ändern, aber wahrscheinlich alle Zeilen ignoriert werden, weil sie alle haben Tab und Titel.

+2

Was ist Ihre erwartete Ausgabe? – fedorqui

Antwort

0

Von Mann diff, wenn ich mich gut erinnere, die -I ignoriert nur die reg exp darin enthalten. Was bedeutet, dass, wenn f1:

the pen is on the table 

und f2 ist:

the pun is on the table 

würde richtig analysieren:

diff -I 'p.n' f2 f2 

geben nichts

ABER

wenn f2 wird nun

the pun is on the cable 

die regexp wird nicht mehr abgestimmt (Kabel und Tisch nicht durch den regulären Ausdruck abgestimmt ...) und so würde u die beiden Linien in der Ausgabe kommen ...

Also, versuchen Sie nur in den Befehl zu ändern:

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

, die den Trick tun sollen (sorry für die dummen Beispiele ..)

+1

Es hat nicht funktioniert. –

3

Dieses Verhalten in der Tat ein wenig seltsam aussieht. Ich bemerkte etwas von Ihren Eingabedateien Tweaking (Ich zog die "Memory" Linie nach oben auf beiden Dateien):

file1.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}} 

file2.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}} 

A Plain Diff gibt Ihnen:

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}} 

Beachten Sie, dass es jetzt zwei Sätze von Unterschieden gibt ...mit dieser Anordnung der diff -I 'Memory' file1.txt file2.txt Befehl wird Arbeit und Ausgang dieser:

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

Bedeutung, die -I Flagge scheint nur zu funktionieren, wenn jede Zeile in einer Reihe von Differenzen den Ausdruck übereinstimmt. Ich weiß nicht, ob das ein Fehler oder erwartetes Verhalten ist ... aber es ist sicherlich inkonsequent.


EDIT: tatsächlich, gemäß dem GNU diff documentation, ist es das erwartete Verhalten. Die Manpage ist nicht so klar. OpenBSD diff hat auch eine -I Flagge, aber their man page erklärt es besser.

3

Dieses Verhalten ist normal, da diff funktioniert (Stand April 2013).

diff ist zeilenorientiert, dh eine Linie wird entweder als völlig anders oder als völlig gleichwertig betrachtet. Wenn eine Zeile ignoriert wird, wird sie vor dem Vergleich in die Liste der verschiedenen Zeilen eingetragen, und wenn das Änderungsskript berechnet wird, werden Änderungen, die nur von ignorierten Zeilen vorgenommen werden, als ignoriert betrachtet. Wenn ignorierte Zeilen an geänderte Zeilen angrenzen, bildet es eine einzige nicht ignorierte Änderung.

Das Problem liegt in der Unfähigkeit der diff zu verstehen, dass aufeinanderfolgende Zeilen nicht verwandt sind: Sie sind eine Folge von Text nicht diffing (was diff richtet sich an), sondern eine Liste der unabhängigen Linien der getastet werden (Tab >= <key>) . Diese Probleme scheinen ziemlich ähnlich zu sein, wenn beide Dateien in der gleichen Reihenfolge generiert werden, aber immer noch nicht gleich sind.

0

Dieses Verhalten gemäss diffutils manuellen erwartet wird:

jedoch -I nur ignoriert das Einfügen oder Löschen von Zeilen, die den regulären Ausdruck wenn jede veränderte Zeile in den HUNK (jede Einfügung enthalten und jedes Löschen) entspricht dem regulären Ausdruck.

Mit anderen Worten, für jede nicht ignorierbare Änderung, diff druckt den vollständigen Satz von Änderungen in seiner Nähe, einschließlich der ignorierbaren. Sie können mehr als einen regulären Ausdruck für zu ignorierende Zeilen angeben, indem Sie mehr als eine Option -I verwenden. diff versucht, jede Zeile mit jedem regulären Ausdruck abzugleichen, beginnend mit dem letzten angegebenen. (man diff)

Sie können versuchen, durch die Angabe -d eine kleinere Menge von Änderungen einzustellen, aber in Ihrem Beispiel wird es nicht funktionieren.

-d --minimal Versuchen Sie, eine kleinere Reihe von Änderungen zu finden.

1

Nun, Sie lernen jeden Tag etwas Neues. Ich war gleichermaßen verwirrt und frustriert von diesem Verhalten, das grob zu sein scheint [diff die Eingabedateien, dann filtere das RE] anstatt [das RE aus den Eingabedateien zu filtern, dann diff].

Ich hätte den zweiten Ansatz natürlicher und nützlicher gedacht. Dies scheint zum Beispiel der Fall zu sein --ignore-case und --strip-trailing-cr arbeiten und passen die Eingabedateien vor dem Diffing an. Um das zu erreichen, was der Fragesteller wollte, müssen Sie außerdem beide Eingaben in temporäre Dateien filtern, sie diffundieren und dann entfernen. Es wird noch mühsamer, wenn Sie wie ich einen rekursiven Unterschied machen wollen.

Ich bestätige, dass diff die Art und Weise wie es dokumentiert ist, anstatt, wie ich es will verhalten, aber respektvoll vorschlägt, dass diese Option (und ähnlich für -b, -w auch) nützlich sein könnte, um Diff.

Verwandte Themen