GNU/Linux >> Tutoriales Linux >  >> Linux

¿Diff -r solo para ciertos tipos de archivos?

¿Hay alguna manera de que pueda realizar una diferenciación recursiva de dos directorios pero solo comparar (en sus lugares respectivos) archivos que coincidan con un predicado de nombre de archivo o tipo de archivo específico?

P.ej. Me gustaría hacer algo Me gusta

diff -r dir-a dir-b -filenames *.java, ivy.xml, build.xml

… o incluso mejor:

diff -r dir-a dir-b -filetype text

Claramente no es obligatorio usar diff como supongo que un encantamiento con find y -exec diff también podría funcionar (simplemente no sé cómo generar las rutas de archivo complementarias en el último caso).

Respuesta aceptada:

Shellscript differ-r

Este shellscript puede realizar una diferencia recursiva de dos directorios, pero solo compara (en sus lugares respectivos) archivos que coinciden con un nombre de archivo específico o un patrón de tipo de archivo.

#!/bin/bash

greenvid="\0033[32m"
resetvid="\0033[0m"

if [ $# -ne 3 ]
then
 echo "Usage: compare files in two directories including subdirectories"
 echo "         $0 <source-dir> <target-dir> <pattern>"
 echo "Example: $0  subdir-1     subdir-2     \"*.txt\""
 exit
fi

cmd='for pathname do
        greenvid="\0033[32m"
        resetvid="\0033[0m"
        echo -e "${greenvid}diff \"$pathname\" \"${pathname/'\"$1\"'/'\"$2\"'}\"${resetvid}"
        diff "$pathname" "${pathname/'\"$1\"'/'\"$2\"'}"
    done'
#echo "$cmd"

find "$1" -type f -name "$3" -exec bash -c "$cmd" bash {} +

Demostración

Archivos:

$ find -type f
./1/ett.txt
./1/two.doc
./1/t r e.txt
./1/sub/only-one.doc
./1/sub/hello.doc
./1/sub/hejsan.doc
./differ-r2
./differ-r1
./differ-r
./2/ett.txt
./2/two.doc
./2/t r e.txt
./2/sub/hello.doc
./2/sub/hejsan.doc

Uso:

$ ./differ-r
Usage: compare files in two directories including subdirectories
         ./differ-r <source-dir> <target-dir> <pattern>
Example: ./differ-r  subdir-1     subdir-2     "*.txt"

Ejecutando differ-r :

El diff realizado las líneas de comando se imprimen con texto verde y la salida, cuando no hay ninguna coincidencia, se imprime con el texto predeterminado (blanco sobre negro en la siguiente captura de pantalla).

$ ./differ-r 1 2 "*.doc"
diff "1/two.doc" "2/two.doc"
diff "1/sub/only-one.doc" "2/sub/only-one.doc"
diff: 2/sub/only-one.doc: No such file or directory
diff "1/sub/hello.doc" "2/sub/hello.doc"
2d1
< world
diff "1/sub/hejsan.doc" "2/sub/hejsan.doc"

$ ./differ-r 1 2 "*.txt"
diff "1/ett.txt" "2/ett.txt"
2c2
< stabben
---
> farsan
diff "1/t r e.txt" "2/t r e.txt"
1c1
< t r e
---
> 3
$ 

$ ./differ-r 1 2 "*"
diff "1/ett.txt" "2/ett.txt"
2c2
< stabben
---
> farsan
diff "1/two.doc" "2/two.doc"
diff "1/t r e.txt" "2/t r e.txt"
1c1
< t r e
---
> 3
diff "1/sub/only-one.doc" "2/sub/only-one.doc"
diff: 2/sub/only-one.doc: No such file or directory
diff "1/sub/hello.doc" "2/sub/hello.doc"
2d1
< world
diff "1/sub/hejsan.doc" "2/sub/hejsan.doc"

$ ./differ-r 2 1 "*"
diff "2/ett.txt" "1/ett.txt"
2c2
< farsan
---
> stabben
diff "2/two.doc" "1/two.doc"
diff "2/t r e.txt" "1/t r e.txt"
1c1
< 3
---
> t r e
diff "2/sub/hello.doc" "1/sub/hello.doc"
1a2
> world
diff "2/sub/hejsan.doc" "1/sub/hejsan.doc"

rsync con filtro

Si no necesita obtener ningún resultado que describa la diferencia, solo sepa qué archivos son diferentes o faltan (para que rsync le gustaría copiarlos), puede usar la siguiente línea de comando.

rsync --filter="+ <pattern>" --filter="+ */" --filter="- *"--filter="- */"  -avcn <source directory>/ <target directory>

Demostración

$ rsync --filter="+ *.doc" --filter="+ */" --filter="- *"  -avcn 1/ 2
sending incremental file list
./
sub/
sub/hello.doc
sub/only-one.doc

sent 276 bytes  received 35 bytes  622.00 bytes/sec
total size is 40  speedup is 0.13 (DRY RUN)

sent 360 bytes  received 41 bytes  802.00 bytes/sec
total size is 61  speedup is 0.15 (DRY RUN)
[email protected] /media/multimed-2/test/test0/temp $ rsync --filter="+ *.txt" --filter="+ */" --filter="- *" -avcn 1/ 2
sending incremental file list
./
ett.txt
t r e.txt
sub/

sent 184 bytes  received 29 bytes  426.00 bytes/sec
total size is 21  speedup is 0.10 (DRY RUN)

Si desea una salida limpia sin líneas de comentario y sin directorios, puede grep la salida así,

$ pattern="*.doc"; rsync --filter="+ $pattern" --filter="+ */" --filter="- *"  -avcn 1/ 2 | grep "${pattern/\*/.\*}"
sub/hello.doc
sub/only-one.doc

Shellscript rsync-diff

Este one-liner se puede convertir en el comando central de un shellscript rsync-diff .

#!/bin/bash

LANG=C

if [ $# -ne 3 ]
then
 echo "Usage: compare files in two directories including subdirectories"
 echo "         $0 <source-dir> <target-dir> <pattern>"
 echo "Example: $0  subdir-1     subdir-2     \"*.txt\""
 exit
fi

pattern="$3"; rsync --filter="+ $pattern" --filter="+ */" --filter="- *" \
 -avcn "$1"/ "$2" | grep "${pattern//\*/.\*}" | grep -v \
  -e '/$' \
  -e '^sending incremental file list$' \
  -e '^sent.*received.*sec$' \
  -e '^total size is.*speedup.*(DRY RUN)$'

Linux
  1. Rsync, ¿incluir solo ciertos tipos de archivos excluyendo algunos directorios?

  2. ¿Existe un delineador para verificar el archivo?

  3. Rsync ¿Dos tipos de archivos en un solo comando?

  4. ¿Para qué sirven los archivos .la de libtool?

  5. Medir el espacio en disco de ciertos tipos de archivos en conjunto

Comando ls en Linux para listar archivos

Exa:un reemplazo moderno para el comando ls

rsync copia solo ciertos tipos de archivos usando la opción de inclusión

¿Cómo puedo encontrar archivos que solo tienen ciertos permisos para el propietario?

sys/types.h:No existe tal archivo o directorio

¿Esta guía de estudio es incorrecta acerca de los comandos para determinar los tipos de archivos?