2013-04-04 19 views
6

mam następujące pliki:Dlaczego różnice z ignorowaniem pasujących wierszy nie działają zgodnie z oczekiwaniami?

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

I biegnę następujące polecenie:

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

który wyprowadza :

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

Jednak mój oczekiwana produkcja jest:

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

Należy zauważyć, że w poleceniu jeśli zmienię „Memory” do „Tab” lub rozwiązać „Tytuł” ​​problemem, ale prawdopodobnie wszystkie linie są ignorowane przyczyna wszyscy mają Tabulator i tytuł.

+2

Jakie są twoje oczekiwane wyniki? – fedorqui

Odpowiedz

0

Od man diff, jeśli dobrze pamiętam, -I po prostu ignoruje reg exp zawarty w nim. Co oznacza, że ​​jeśli F1:

the pen is on the table 

i F2 jest:

the pun is on the table 

będzie poprawnie analizować:

diff -I 'p.n' f2 f2 

dając nic

BUT

jeśli F2 staje się teraz

the pun is on the cable 

regexp nie pasuje już (kabel i tabela nie są dopasowane przez regexp ...) i tak u miałby dwie linie zbliża się do wyjścia ...

Więc, po prostu spróbuj zmienić komendę:

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

że powinno wystarczyć (przepraszam za głupie przykłady ..)

+1

To nie zadziałało. –

3

Takie zachowanie rzeczywiście wygląda nieco dziwnie. Zauważyłem coś przez szczypanie plików wejściowych (ja po prostu przeniósł linię „Pamięć” na górze po obu plików):

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

plain diff da ci:

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

Zauważ, że teraz istnieją dwa zestawy różnic ...z tego układu, komenda diff -I 'Memory' file1.txt file2.txtbędzie pracy i wyjście tym:

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

znaczenie, flaga -I wydaje się działać tylko wtedy, gdy każdy wiersz w zestawie różnice pasuje do wyrażenia. Nie wiem, czy to błąd, czy oczekiwane zachowanie ... ale z pewnością jest niespójne.


EDIT: rzeczywiście, jak na GNU diff documentation, jest to oczekiwane zachowanie. Strona podręcznika nie jest tak jasna. OpenBSD diff ma także flagę -I, ale lepiej to tłumaczy their man page.

3

To zachowanie jest normalne, ponieważ działa diff (stan na kwiecień 2013).

jest zorientowany na linię, oznacza to, że linia jest uważana za całkowicie inną lub całkowicie równoważną. Kiedy linia jest ignorowana, zostaje wpisana na listę różnych linii przed porównaniem, a kiedy obliczany jest skrypt zmiany, zmiany tylko ignorowanych linii są uważane za ignorowane. Gdy linie ignorowane sąsiadują ze zmienionymi liniami, tworzy jedną niezignorowaną zmianę.

Problem polega na niezdolności diff do zrozumienia, że ​​kolejne linie nie są powiązane: nie jesteś diffing ciąg tekstu (co diff jest skierowany), ale raczej lista niezależnych linii, które są oznaczone (Tab >= <key>) . Problemy te wydają się podobne, gdy oba pliki są generowane w tej samej kolejności, ale wciąż nie są takie same.

0

Jest to oczekiwane zachowanie, jak na diffutils instrukcji:

Jednak -I tylko ignoruje wstawiania lub usuwania wierszy, które zawierają wyrażenie regularne jeśli każdy zmieniona linia w przystojniak (każdy wkładania i każde usunięcie) pasuje do wyrażenia regularnego.

Innymi słowy, dla każdej niezużytej zmiany, diff drukuje komplet zmian w jego pobliżu, w tym niezapomniane. Można określić więcej niż jedno wyrażenie regularne do ignorowania linii, używając więcej niż jednej opcji -I. diff próbuje dopasować każdą linię do każdego wyrażenia regularnego, zaczynając od ostatniego podanego. (man diff)

Możesz spróbować ustawić mniejszy zestaw zmian, określając -d, ale na swoim przykładzie, że nie będzie działać.

-d --minimal Staraj się znaleźć mniejszy zestaw zmian.

1

Cóż, każdego dnia uczysz się czegoś nowego. Byłem równie zagubiony i sfrustrowany tym zachowaniem, które wydaje się z grubsza [odróżnić pliki wejściowe, a następnie odfiltrować RE], a nie [odfiltrować RE z plików wejściowych, a następnie porównać].

Wydaje mi się, że drugie podejście jest bardziej naturalne i bardziej użyteczne. Na przykład wygląda na to, że działa --ignore-case i --strip-trailing-cr, dostosowując pliki wejściowe przed porównaniem. Ponadto faktyczne osiągnięcie tego, co chciał zapytać, polega na filtrowaniu obu danych wejściowych do plików tymczasowych, ich porównywaniu, a następnie ich usuwaniu. Staje się to jeszcze bardziej nużące, jeśli chcesz zrobić rekurencyjną różnicę, tak jak ja.

Przyjmuję do wiadomości, że diff zachowuje się w taki sposób, w jaki jest dokumentowany, a nie jak powinien się zachować, ale z szacunkiem sugeruję, że ta opcja (i podobnie dla -b, -w) mogłaby być użytecznie dodana do diff.