2013-04-04 5 views
6

Ho i seguenti file:Perché diff con ignorare le linee di corrispondenza non funziona come previsto?

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

E sto eseguendo il comando seguente:

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

che emette :

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

Tuttavia il mio risultato atteso è:

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

Si noti che nel comando se cambio 'memoria' a 'Tab' o di 'Titolo' problema risolto, ma probabilmente tutte le linee vengono ignorate perché tutti hanno Scheda e titolo.

+2

Qual è il tuo output previsto? – fedorqui

risposta

0

Da uomo diff, se ricordo bene, il -I ignora solo il reg exp contenuto in esso. Il che significa che se f1 è:

the pen is on the table 

e f2 è:

the pun is on the table 

sarebbe analizzare correttamente:

diff -I 'p.n' f2 f2 

dare nulla

MA

se f2 diventa ora

the pun is on the cable 

regexp non corrisponde più (cavo e tabella non sono abbinati dal regexp ...) e quindi u avrebbe le due linee in arrivo nell'output ...

Quindi, basta provare a cambiare il comando in:

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

che dovrebbe fare il trucco (mi dispiace per gli esempi stupidi ..)

+1

Non ha funzionato. –

3

Questo comportamento sembra davvero un po 'strano. Ho notato qualcosa modificando i file di input (Ho appena spostato la linea di "Memory" per la parte superiore su entrambi i file):

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 diff diff vi darà:

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

Si noti che ci sono due serie di differenze ora ...con questa disposizione, il diff -I 'Memory' file1.txt file2.txt comando volontà lavoro e uscita questo:

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

significato, il flag -I sembra funzionare solo quando ogni linea in una serie di differenze corrisponde all'espressione. Non so se questo è un bug o un comportamento previsto ... ma è certamente incoerente.


EDIT: in realtà, come per la GNU diff documentation, è il comportamento previsto. La pagina man non è così chiara. OpenBSD diff ha anche il flag -I, ma lo their man page lo spiega meglio.

3

Questo comportamento è normale dato il modo in cui funziona diff (ad aprile 2013).

diff è orientato alla linea, ovvero una linea è considerata totalmente diversa o totalmente equivalente. Quando una riga viene ignorata, viene inserita nell'elenco di righe diverse prima del confronto e quando lo script di modifica viene calcolato, le modifiche apportate solo alle righe ignorate vengono considerate come ignorate. Quando le linee ignorate sono adiacenti alle linee modificate, costituiscono una singola modifica non ignorata.

Il problema sta nella incapacità di diff per capire che le linee consecutive non sono collegati: non si diffing una sequenza di testo (quello diff si rivolge a), ma piuttosto un elenco di linee indipendenti che sono calettati (Tab >= <key>) . Questi problemi sembrano abbastanza simili quando entrambi i file sono generati nello stesso ordine, ma non sono uguali.

0

Ciò è il comportamento secondo diffutils manuale:

Tuttavia, -I solo ignora l'inserimento o l'eliminazione di righe che contengono l'espressione regolare se ogni linea modificata nel pezzo (ogni inserimento e ogni cancellazione) corrisponde all'espressione regolare.

In altre parole, per ogni modifica non ignorabile, diff stampa il set completo di modifiche nelle sue vicinanze, comprese quelle ignorabili. È possibile specificare più di un'espressione regolare per le righe da ignorare utilizzando più di un'opzione -I. diff tenta di associare ogni riga a ciascuna espressione regolare, a partire dall'ultima data. (man diff)

Puoi provare a impostare un insieme ridotto di modifiche specificando -d, ma nel tuo esempio non funzionerà.

-d --minimal Provare a trovare un insieme più piccolo di modifiche.

1

Bene, impari qualcosa di nuovo ogni giorno. Ero ugualmente confuso e frustrato da questo comportamento, che sembra essere grosso modo [diff i file di input, quindi filtrare l'RE] piuttosto che [filtrare l'RE dai file di input, quindi diff].

Avrei pensato che il secondo approccio fosse più naturale e più utile. Ad esempio questo sembra essere il modo in cui -ignore-case e --strip-trailing-cr, regolando i file di input prima di diffonderli. Inoltre, in realtà ottenere ciò che l'interrogante desiderava consisteva nel filtrare entrambi gli input in file temporanei, differenziandoli, quindi rimuovendoli. Diventa ancora più noioso se vuoi fare una diff ricorsiva come ho fatto io.

Riconosco che diff si comporta come è documentato piuttosto che come voglio che si comporti, ma suggerisco rispettosamente che questa opzione (e simile per -b, -w anche) possa essere utilmente aggiunta a diff.