Come posso fare in modo che 'diff -X' ignori percorsi specifici e non nomi di file?


29

fare: diff -r -X <ignore-list> <src-dir> <dest-dir>

non sembra diffignorare le voci <ignore-list>se sono del modulo <dir>/<file>.

Le voci del modulo <file> vengono comunque prese in considerazione. Questo è un problema poiché potrei avere più file nominati <file>in diverse sottodirectory, alcune delle quali non voglio essere ignorata.

Non sembrano esserci molte informazioni riguardo la sintassi del pattern nella manpage per diffentrambi. Da quello che posso dire, è solo il nome di base di un file che viene considerato da diff (vedi http://forums.gentoo.org/viewtopic-t-889788-start-0.html se sei interessato).


amico, l diff' --excludeopzione è così
merdosa

Risposte:


30

Le directory di elenco dovrebbero funzionare; ad esempio, ecco cosa ho usato in uno script (supponendo gnu diff),

diff -r \
   --exclude="*~" \
   --exclude=".svn" \
   --exclude=".git" \
   --exclude="*.zip*" \
   --exclude="*.gz" \
   --exclude="*.tar" \
   ...etc

... che ignora i contenuti di .svne .gitdirs, ma anche i singoli file denominati *.zip/ *.gz/ etc.

Modifica: per filtrare i percorsi del modulo dir_a/file1ma ancora i difffile con lo stesso nome di base, come dir_b/file1o dir_a/b/file1, quindi diffdovrebbe essere generato un elenco di file (ad esempio, utilizzando find) e il file da confrontare derivato da questi percorsi; ad es. dato

$ find ONE TWO -type f -print 
ONE/a/1.txt
ONE/a/2.txt
ONE/a/b/2.txt
TWO/a/1.txt
TWO/a/2.txt
TWO/a/b/2.txt

si genera l'elenco di file da confrontare, escludendo ad esempio */a/2.txtma confrontando comunque altri file denominati 2.txt. Basta "trovare" tutti i file tranne ONE/a/2.txt(un regexp può essere utilizzato anche qui, come .*/a/2.txt)

$ find ONE -type f \( ! -regex 'ONE/a/2.txt' \) \
    -exec bash -c 'diff -q "${1}" "${2/ONE/TWO}"' - {} {} \;  

che in effetti ignora ONE/a/2.txt(e TWO/a/2.txt), ma confronta ancora gli altri file chiamati 2.txt:

diff -q ONE/a/1.txt TWO/a/1.txt
diff -q ONE/a/b/2.txt TWO/a/b/2.txt

Modifica: Oppure, più divertente con find(ulteriore divertimento lasciato come esercizio per il lettore), seleziona i file o le directory da escludere e poi difftutto il resto:

$ find ONE \( -regex 'ONE/a/2.txt' -o -name b  -prune \)  \
    -o -type f -exec bash -c 'echo diff -q "${1}" "${2/ONE/TWO}"' - {} {} \

L'esempio sopra esclude il file specifico "{top} /a/2.txt", qualsiasi directory denominata "b" e tutto il resto è diff. (Invece del semplice " -name b" potresti anche usare " -regex '.*/b'" - note, no trailing "/".)


2
Grazie ma penso che ti manchi il punto. L'unico supporto che sembra esserci è quando usi un "nome-base". Potrebbe essere il nome di una directory o di un file. In entrambi i casi, diff ignora ciò che hai chiesto. Il problema sorge quando si utilizzano i percorsi. Ad esempio, non riesco a far diff per ignorare / an / absolute / path / to / a / file o ./a/relative/path/to/a/file.
Ash,

2
diff --exclude = "/ this / specific / file / that / im / esplicitamente / supplicando / tu / to / ignora". Non funzionerà
Ash,

3
corretto, i excludepattern sono abbinati al basename dei file (come da gnu.org/software/diffutils/manual/html_node/… ); i percorsi non funzioneranno (come in foo/bar.txt). Per fare ciò, probabilmente dovrai eseguire findper generare l'elenco di nomi di file e derivare il percorso del file da confrontare.
michael,

risposta aggiornata per includere l'esempio escludendo i percorsi dei file da diff, invece di usare semplicementebasename
michael

Ok, capisco cosa stai proponendo, ma sembra che ci sia un problema. Devo considerare anche le directory, non solo i file (es. -Tipo f). Ora, mentre puoi ancora eliminare determinati file usando regexp con find, se l'input in diffcontiene una directory, passerà attraverso e confronterà i file all'interno di quella directory e alcuni di questi file potrebbero dover essere ignorati .... torna al quadrato 1.
Ash


1

Per escludere la directory directory/sub-directory, io uso

diff -r <src-dir> <dest-dir> | grep -v directory/sub-directory

Tuttavia, sebbene dovrebbe funzionare per una singola esclusione, non dovrebbe essere possibile per un lungo elenco di ignorare come hai fatto tu.


-2
$ diff -rq foo.orig foo | grep -vP 'ignore1/|exclude2/' | awk '{print $2}' | cut -d'/' -f2- | xargs -I{} diff -u foo.orig/{} foo/{}

1
Sebbene ciò possa rispondere alla domanda, sarebbe una risposta migliore se tu potessi fornire qualche spiegazione sul perché lo faccia.
David Post
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.