Come posso ottenere diff per mostrare solo le linee aggiunte ed eliminate? Se diff non può farlo, quale strumento può farlo?
diff A B | grep '^[<>]'
comm
.
Come posso ottenere diff per mostrare solo le linee aggiunte ed eliminate? Se diff non può farlo, quale strumento può farlo?
diff A B | grep '^[<>]'
comm
.
Risposte:
Un altro modo di vederlo:
Mostra le righe che esistono solo nel file a: (ovvero ciò che è stato eliminato da a)
comm -23 a b
Mostra le righe che esistono solo nel file b: (ovvero ciò che è stato aggiunto a b)
comm -13 a b
Mostra le righe che esistono solo in un file o nell'altro: (ma non entrambi)
comm -3 a b | sed 's/^\t//'
(Avviso: se il file a
ha righe che iniziano con TAB, esso (il primo TAB) verrà rimosso dall'output.)
NOTA: entrambi i file devono essere ordinati per comm
funzionare correttamente. Se non sono già ordinati, è necessario ordinarli:
sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted
Se i file sono estremamente lunghi, questo può essere piuttosto oneroso in quanto richiede una copia aggiuntiva e quindi il doppio dello spazio su disco.
comm -12 <(sort a) <(sort b)
comm
potrebbe fare quello che vuoi. Dalla sua pagina man:
DESCRIZIONE
Confronta i file ordinati FILE1 e FILE2 riga per riga.
Senza opzioni, produce output a tre colonne. La colonna uno contiene righe univoche per FILE1, la colonna due contiene righe univoche per FILE2 e la colonna tre contiene righe comuni a entrambi i file.
Queste colonne sono suppressable con -1
, -2
e -3
rispettivamente.
Esempio:
[root@dev ~]# cat a
common
shared
unique
[root@dev ~]# cat b
common
individual
shared
[root@dev ~]# comm -3 a b
individual
unique
E se vuoi solo le linee uniche e non ti importa in quale file si trovano:
[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique
Come dice la pagina man, i file devono essere ordinati in anticipo.
Per mostrare aggiunte ed eliminazioni senza contesto, numeri di riga, +, -, <,>! ecc., puoi usare diff in questo modo:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
Ad esempio, dati due file:
a.txt
Common
Common
A-ONLY
Common
b.txt
Common
B-ONLY
Common
Common
Il comando seguente mostrerà le linee rimosse da a o aggiunte a b:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
produzione:
B-ONLY
A-ONLY
Questo comando leggermente diverso mostrerà le linee rimosse da a.txt:
diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt
produzione:
A-ONLY
Infine, questo comando mostrerà le linee aggiunte ad a.txt
diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt
produzione
B-ONLY
Questo è ciò che fa diff per impostazione predefinita ... Forse devi aggiungere alcuni flag per ignorare gli spazi bianchi?
diff -b -B
dovrebbe ignorare le righe vuote e diversi numeri di spazi.
No, in diff
realtà non mostra le differenze tra due file nel modo in cui uno potrebbe pensare. Produce una sequenza di comandi di modifica per uno strumento come patch
utilizzare per cambiare un file in un altro.
La difficoltà per qualsiasi tentativo di fare ciò che stai cercando è come definire ciò che costituisce una linea che è cambiata rispetto a una cancellata seguita da una aggiunta. Anche cosa fare quando le linee vengono aggiunte, eliminate e modificate l'una accanto all'altra.
diff
fonti, ma mi sembra di ricordare tutti i tipi di rotazioni per tenere traccia di dove due file corrispondono per rimanere sincronizzati e penso che ci sia una soglia per rinunciare in base alla distanza le linee sono. Ma non ricordo alcuna corrispondenza intra-line tranne che per lo spazio bianco (facoltativamente) compresso o ignorando il caso. O (forse) parole per quell'effetto. In ogni caso, si tratta solo di patch
"vgrep". Può essere. Martedì.
Gli strumenti di confronto visivo adattano due file insieme in modo che un segmento con lo stesso numero di linee ma con contenuto diverso verrà considerato un segmento modificato. Le linee completamente nuove tra i segmenti corrispondenti sono considerate segmenti aggiunti.
Questo è anche il modo in cui funziona lo strumento da riga di comando sdiff , che mostra un confronto fianco a fianco di due file in un terminale. Le righe modificate sono separate da | carattere. Se esiste una riga solo nel file A, <viene utilizzato come carattere di separazione. Se esiste una riga solo nel file B,> viene utilizzato come separatore. Se non hai <e> caratteri nei file, puoi usarlo per mostrare solo le righe aggiunte:
sdiff A B | grep '[<>]'
Grazie senarvi, la tua soluzione (non votata per) in realtà mi ha dato ESATTAMENTE quello che volevo dopo aver cercato per anni su una tonnellata di pagine.
Usando la tua risposta, ecco cosa mi è venuto in mente per far cambiare / aggiungere / cancellare l'elenco delle cose. L'esempio utilizza 2 versioni del file / etc / passwd e stampa il nome utente per i record pertinenti.
#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'
Trovo questa forma particolare spesso utile:
diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g
Esempio:
printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
Produzione:
-b
-c
+B
+C
-e
-f
+E
+F
Quindi mostra le vecchie linee con -
seguite immediatamente dalla corrispondente nuova linea con +
.
Se avessimo cancellato C
:
printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
sembra così:
-b
+B
+C
-e
-f
+E
+F
Il formato è documentato su man diff
:
--line-format=LFMT
format all input lines with LFMT`
e:
LTYPE is 'old', 'new', or 'unchanged'.
GTYPE is LTYPE or 'changed'.
e:
LFMT (only) may contain:
%L contents of line
%l contents of line, excluding any trailing newline
[...]
Domanda correlata: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux
Testato su Ubuntu 18.04.
file1:
text670_1
text067_1
text067_2
file2:
text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1
Uso:
diff -y file1 file2
Questo mostra due colonne per i file ripetitivi.
Produzione:
text670_1
> text04_1
> text04_2
> text05_1
> text05_2
text067_1 text67_1
text067_2 text67_2
> text1000_1