2009-10-14 18 views
37

Ho bisogno di lavorare con file di grandi dimensioni e devo trovare le differenze tra due. E non ho bisogno dei diversi bit, ma del numero di differenze.Come contare le differenze tra due file su linux?

Per trovare il numero di righe diverse vengo con

diff --suppress-common-lines --speed-large-files -y File1 File2 | wc -l 

e funziona, ma c'è un modo migliore per farlo?

E come contare il numero esatto di differenze (con strumenti standard come bash, diff, awk, qualche vecchia versione di perl)?

risposta

31
diff -U 0 file1 file2 | grep -v ^@ | wc -l 

Questo meno 2 per i due nomi di file nella parte superiore della lista diff. Il formato unificato è probabilmente un po 'più veloce del formato side-by-side.

+5

Questo non funziona, come io definisco "di lavoro" http: // pastie. org/paste/3179433/text Ci sono solo un carattere in ogni file, a cosa si riferisce il numero "4"? –

+0

Questo funziona. Per il tuo esempio hai quattro righe: le prime due sono il nome di ciascun file (come spiegato nella risposta), e le altre due sono le due differenze, 1 riga con 'a' rimossa e 1 riga con 'b' aggiunta. –

+4

Dipende da come si contano le differenze. In questo esempio [pastie.org/5553254](http://pastie.org/5553254), considero che ci sono 2 righe che differiscono, cioè sono d'accordo con sequoia mcdowell. È anche scomodo dover sottrarre 2 dal risultato (a causa della stampa dei 2 file diff: ed). Pertanto, penso che la risposta di Josh sia corretta. Può essere leggermente abbreviato usando l'opzione -c (count) su grep, invece di piping su wc -l, come questo: 'diff -U 0 file1 file2 | grep -c^@ ' –

6

Se si usa Linux/Unix, che dire di comm -1 file1 file2 stampare linee in file1 che non sono in file2, comm -1 file1 file2 | wc -l a contarli, e allo stesso modo per comm -2 ...?

+0

Come il sureshw indica in un'altra risposta, 'comm' si aspetta i suoi argomenti devono essere * ordinati * file. Quindi questo suggerimento può essere invocato solo in casi speciali.(Penso che sarebbe facile scrivere la propria versione di 'comm' usando awk che ha funzionato anche per input non ordinati, ma dubita che questo soddisfi più lo spirito della domanda originale.) – dubiousjim

40

Se si desidera contare il numero di linee che sono uso diverso questa:

diff -U 0 file1 file2 | grep ^@ | wc -l 

Vuol risposta non Giovanni doppia contano le diverse linee?

+0

Sì, conta due volte. Vedi il mio commento sulla risposta accettata. Il comando in questa risposta è corretto. –

+2

Sembra che contenga anche due linee di conteggio doppio, sia su MacOSX che su Ubuntu. I lotti di linee contigue possono essere raggruppati in un unico blocco e dipende dal tuo compito se debba essere o meno una differenza o più. – khedron

+0

Non dimenticare l'output colorato significa che le linee iniziano con una sequenza di escape! Ho dovuto usare hexdump per capirlo. –

4

Dal momento che ogni linea di uscita che si differenzia inizia con < o > carattere, vorrei suggerire questo:

diff file1 file2 | grep ^[\>\<] | wc -l 

Utilizzando solo \< o \> nella linea di script è possibile contare le differenze solo in uno dei file.

+0

Questo doppio conteggio delle righe come "<" and ">" può essere stampato per la stessa riga . –

0

Se si ha a che fare con file con contenuto analogo, è necessario ordinare la stessa riga per riga (come i file CSV che descrivono cose simili) e si potrebbe ad es. vuole trovare 2 differenze nei seguenti file:

File a: File b: 
min,max min,max 
1,5  2,5 
3,4  3,4 
-2,10  -1,1 

si potrebbe implementare in Python come questo:

different_lines = 0 
with open(file1) as a, open(file2) as b: 
    for line in a: 
     other_line = b.readline() 
     if line != other_line: 
      different_lines += 1 
Problemi correlati