2010-09-23 14 views
57

Tengo una pregunta sobre el comando diff si quiero una diferencia de directorio recursivo pero solo para un tipo de archivo específico, ¿cómo hacerlo?¿Cómo se diferencia un directorio para solo archivos de un tipo específico?

He intentado utilizar la opción excluye, sino que sólo puede utilizar un solo patrón:

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

con el comando sólo puede excluir tipo de archivo XML, a pesar de que hay archivos en el tipo de imagen de carpeta (png, gif , jpg), txt, php, etc.

cómo modificar solo ciertos tipos de archivos.

+0

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

Respuesta

67

Puede especificar -x más de una vez.

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

Desde la sección Directorios Comparación de info diff (en mi sistema, tengo que hacer info -f /usr/share/info/diff.info.gz):

Ignorar algunos archivos mientras se compara directorios, utilice el '-x patrón' o " --exclude = opción PATTERN '. Esta opción ignora cualquier archivo o subdirectorios cuyos nombres base coinciden con el patrón de shell PATTERN. A diferencia del shell, un punto al comienzo de la base de un nombre de archivo coincide con un comodín al inicio de un patrón. Debe incluir PATTERN entre comillas para que el shell no lo expanda. Por ejemplo, la opción -x '*. [Ao]' ignora cualquier archivo cuyo nombre termine con '.a' o '.o'.

Esta opción se acumula si la especifica más de una vez. Para el ejemplo , con las opciones -x 'RCS' -x '*, v' ignora cualquier archivo o subdirectorio cuyo nombre base es 'RCS' o termina con ', v'.

+0

Mine (ubuntu 10.04) no tiene estas líneas. También lo intenté y no funcionó. Supongo que esta es una nueva versión. – alumi

16

Tomado de (una versión de) la página del manual:

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

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

por lo que parece -x sólo acepta un patrón que le informe, pero si pones todos los patrones que desea excluir en un archivo (presumiblemente uno por línea) se puede utilizar la segunda bandera de este modo:

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

donde exclude.pats es:

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

puede encontrar todas las extensiones de los archivos dentro de la carpeta a excepción de la extensión con el siguiente comando línea: 'encontrar. -type f -not -name '*. '| xargs -I% nombre base '%' | awk -F. 'NF> 1 {print "*." $ NF}; NF == 1 {print $ NF} '| ordenar | uniq> exclude.pats' – John

+0

Ojalá hubiera notado el comentario de John anteriormente, pero en macOs/bash llegué a una solución similar para producir el archivo de exclusión con varios patrones para mantener: 'find. -no -name "* .c" -and -not -name "* .h" -and -type f -print0 | xargs -0 nombre básico | grep -E '. * \ .. +' | sed 's /\./\// g' | xargs basename | xargs printf '*.% s \ n' | ordenar | uniq> X-FILE' Quiero creer que ayuda, tal vez en Linux también. (En este ejemplo, un solo '-name" *. [Ch] "' está bien, pero no es muy ilustrativo) – eruve

0

En caso de que lo encuentre conveniente, puede usar el siguiente Makefile. Sólo tiene que ejecutar: "hacer que el parche"

#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 falta de un --include complementaria hace que sea necesario el uso de tales patrones heurísticos enrevesadas como

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

de encontrar (en su mayoría) los archivos java!

0

Si desea diferir las fuentes y que sea sencillo:

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

eliminar el último grep si desea obtener los archivos que existen en solamente uno de los caminos.

4

La falta de un complemento --include ....

Podemos hacer una solución alternativa, un archivo de exclusión con todos los archivos pero lo que queremos incluir. Así creamos fichero1 con un encontrar todos los archivos que no tienen extensiones que queremos incluir, captura sed y el nombre de archivo es simplemente: diff ejemplo --exclude-from = fichero1 RUTA1/RUTA2 /,:

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

Súper útil de una sola línea, thx. En Mac OSX grep es ligeramente diferente y se convierte en 'find PATH1/-type f | grep --text -v -e "php $" -e html $ "| sed 's /.*\///' | sort -u> archivo1 diff PATH1/PATH2/-rq -X archivo1' – mmacvicar

1

también puede utilizar encontrar con -exec llamar diff:

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