Come diff diffondere più file tra le directory?


19

Sto cercando di trovare diffs tra tutti i file con lo stesso nome in due copie di una directory (ad esempio, funzionante e di backup). Ad esempio, posso diffdue file con lo stesso nome in entrambi:

> diff d1/f.cpp d2/f.cpp

o posso trovare differenze tra le directory:

> diff d1 d2

ma come posso trovare differenze solo tra i *.cppfile?

> diff d1/*.cpp d2/*.cpp

non sembra funzionare (per ovvi motivi).

[Probabilmente è facile da risolvere con i loop, ma sto cercando di trovare un modo più elegante]

Risposte:


13

È possibile utilizzare un loop di shell che esegue diff per ciascun file, anche se ciò non rileverà i casi in cui d2 contiene un file, ma d1 no. Potrebbe essere sufficiente però.

for file in d1/*.cpp; do
    diff "$file" "d2/${file##*/}"
done

O tutto su una riga:

for file in d1/*.cpp; do diff "$file" "d2/${file##*/}"; done

La ${file##*/}parte è un'espansione di parametro speciale.

Se la variabile del file contiene d1/hello.cpp, "${file##*/}"si espanderà a hello.cpp(il valore del file, ma con tutto fino a, incluso, l'ultimo / rimosso).

Quindi "d2/${file##*/}"si tradurrà in d2/hello.cppe il comando diff risultante è cosìdiff d1/hello.cpp d2/hello.cpp

Vedi http://mywiki.wooledge.org/BashFAQ/100 per ulteriori informazioni sulle manipolazioni delle stringhe in bash.

Da un lato, un sistema di controllo della versione (come sovversione, git, mercurial ecc ...) renderebbe molto più facile questo tipo di diffing.


Penso che delle due grandi risposte, questo su sia più semplice quando ci sono più tipi di file (anche se ho menzionato nella domanda che sto cercando una soluzione senza loop), quindi l'ho accettato. L'unica aggiunta aggiunta è echo "${file##*/}";prima del diffcomando, quindi si sa quali file vengono effettivamente confrontati. Inoltre, come menzionato nella risposta di @ Rinzwind, questo metodo non copre il caso in cui l'elenco dei file non è esattamente lo stesso in entrambe le directory.
ysap

52

diff -qr {DIR1} {DIR2} fa tutti i file in entrambe le directory.

  • q mostra solo differenze
  • rfa ricorsivo. Lascialo fuori se non ne hai bisogno

Non puoi dire diffdirettamente di usare i caratteri jolly ma puoi aggiungere:

-x PAT  --exclude=PAT
    Exclude files that match PAT.

-X FILE    --exclude-from=FILE
   Exclude files that match any pattern in FILE.

per escludere i file. Quindi, se vuoi solo *.cppil metodo più semplice è creare un file di testo che elenca tutti i file che non lo sono *.cpp. Puoi farlo con il seguente comando: ls -I "*.cpp" > excluded_filesdove l' -I "*.cpp"argomento ignora tutti i file .cpp. Si noti che le virgolette sono necessarie.


Semplice e funziona perfettamente.
Jose Gómez,

4

Qualche tempo dopo aver posto la domanda, ho scoperto l' meldutilità diff e la utilizzo da allora. Questo è un ottimo pezzo di programma basato sulla GUI che rende il confronto e l'unione tra file e directory un compito molto semplice. Fa confronti a due o tre vie.

In particolare, risponde alla mia domanda originale in quanto mostra un confronto con codice colore dei contenuti della directory e consente di confrontare file specifici facendo doppio clic sul nome del file.

Se uno ha bisogno di più di un confronto a tre, allora gvimdiff(basato sull'editor vim) è anche un ottimo strumento che offre questa funzionalità.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.