2010-09-23 8 views
57

Ho una domanda sul comando diff se voglio una directory ricorsiva, ma solo per un tipo di file specifico, come fare?Come si differisce una directory solo per i file di un tipo specifico?

Ho provato ad utilizzare l'opzione di escludere, ma solo usare un solo modello:

$ diff /destination/dir/1 /destination/dir/2 -r -x *.xml 

con il comando posso escludere solo tipo di file XML, anche se ci sono i file nel tipo di immagine della cartella (png, gif , jpg), txt, php, ecc.

come diff solo determinati tipi di file.

+0

https://stackoverflow.com/q/10131908/2707864 –

risposta

67

È possibile specificare -x più di una volta.

diff -x '*.foo' -x '*.bar' -x '*.baz' /destination/dir/1 /destination/dir/2 

Dalla sezione Confrontando le directory di info diff (sul mio sistema, che devo fare info -f /usr/share/info/diff.info.gz):

Per ignorare alcuni file durante il confronto directory, utilizzare il '-x MODELLO' o ' opzione --exclude = PATTERN '. Questa opzione ignora tutti i file o sottodirectory i cui nomi di base corrispondono al pattern PATTERN della shell. A differenza della shell, un punto all'inizio della base di un nome file corrisponde a un carattere jolly all'inizio di un pattern. È necessario includere PATTERN tra virgolette affinché la shell non la espanda. Ad esempio, l'opzione -x '*. [Ao]' ignora qualsiasi file il cui nome termina con '.a' o '.o'.

Questa opzione si accumula se la si specifica più di una volta. Per esempio , utilizzando le opzioni -x 'RCS' -x '*, v' ignora qualsiasi file o sottodirectory il cui nome base è 'RCS' o termina con ', v'.

+0

Il mio (ubuntu 10.04) non ha queste righe. Ho anche provato e non ha funzionato. Immagino che questa sia una nuova versione. – alumi

16

Tratto da (una versione del) la pagina man:

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

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

così sembra -x accetta solo un modello, come si relazione, ma se si mettono tutti i modelli da escludere in un file (presumibilmente uno per riga) è possibile utilizzare la seconda bandiera in questo modo:

$ diff /destination/dir/1 /destination/dir/2 -r -X exclude.pats 

dove exclude.pats è:

*.jpg 
*.JPG 
*.xml 
*.XML 
*.png 
*.gif 
+3

potete trovare tutte le estensioni dei file all'interno della cartella fatta eccezione per la estensione con il seguente comando linea: 'trova. -tipo f -not -name '*. '| xargs -I% basename '%' | awk -F. 'NF> 1 {print "*." $ NF}; NF == 1 {print $ NF} '| ordinare | uniq> exclude.pats' – John

+0

Vorrei aver notato il commento di John prima, ma su macOs/bash sono arrivato a una soluzione simile per produrre il file di esclusione con diversi pattern da conservare: 'find. -not -name "* .c" -and -not -name "* .h" -and -type f -print0 | xargs -0 basename | grep -E '. * \ .. +' | sed 's /\./\// g' | xargs basename | xargs printf '*.% s \ n' | ordinare | uniq> X-FILE 'Voglio credere che aiuti, forse anche su Linux. (In questo esempio un singolo '-name" *. [Ch] "' va bene, ma non è molto illustrativo) – eruve

0

Nel caso in cui lo si trovi conveniente, è possibile utilizzare il seguente Makefile. Basta eseguire: "make patch"

#Makefile for patches 

#Exlude following file endings 
SUFFIX += o 
SUFFIX += so 
SUFFIX += exe 
SUFFIX += pdf 
SUFFIX += swp 

#Exlude following folders 
FOLDER += bin 
FOLDER += lib 
FOLDER += Image 
FOLDER += models 

OPTIONS = Naur 

patch: 
    rm test.patch 
    diff -$(OPTIONS) \ 
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \ 
    $(foreach element, $(FOLDER) , -x '$(element)*') \ 
     org/ new/ > test.patch 

unpatch: 
    rm test.unpatch 
    diff -$(OPTIONS) \ 
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \ 
    $(foreach element, $(FOLDER) , -x '$(element)*') \ 
    new/ org/ > test.unpatch 
0

La mancanza di un --include complementare rende necessario l'utilizzo di tali modelli euristici contorti come

*.[A-Zb-ik-uw-z]* 

per trovare (per lo più) file Java!

0

Se si desidera differire fonti e mantenere le cose semplici:

diff -rqx "*.a" -x "*.o" -x "*.d" ./PATH1 ./PATH2 | grep "\.cpp " | grep "^Files" 

rimuovere l'ultimo grep, se si desidera ottenere i file che esistono solo in uno dei percorsi.

4

La mancanza di un complementare - include ....

Possiamo fare una soluzione alternativa, un file di esclusione con tutti i file ma quello che vogliamo includere. Così creiamo file1 con un trovare tutti i file che non hanno estensioni che vogliamo includere, sed cattura il nome del file ed è solo: diff esempio --exclude-from = file1 PATH1/Percorso 2 /,:

find PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 
diff PATH1/ PATH2/ -rq -X file1 
+0

One-liner super utile, grazie. Su Mac OSX grep è leggermente diverso e diventa 'trova PATH1/-type f | grep --text -v -e "php $" -e html $ "| sed 's /.*\///' | sort -u> file1 diff PATH1/PATH2/-rq -X file1' – mmacvicar

1

È inoltre possibile utilizzare trovare con -exec chiamare diff:

cd /destination/dir/1 
find . -name *.xml -exec diff {} /destination/dir/2/{} \; 
Problemi correlati