tool online files directories linux command-line diff

linux - online - ubuntu compare files



Difunde solo los nombres de los archivos (6)

Estoy buscando ejecutar un comando de Linux que comparará recursivamente dos directorios y generará solo los nombres de los archivos de lo que es diferente. Esto incluye todo lo que está presente en un directorio y no el otro o viceversa, y las diferencias de texto.


Desde la página del manual de diff:

-q Informe solo si los archivos difieren, no los detalles de las diferencias.
-r Al comparar directorios, compara de forma recursiva cualquier subdirectorio encontrado.

Ejemplo de comando:

diff -qr dir1 dir2

Ejemplo de salida (depende de la localización):

$ ls dir1 dir2 dir1: same-file different only-1 dir2: same-file different only-2 $ diff -qr dir1 dir2 Files dir1/different and dir2/different differ Only in dir1: only-1 Only in dir2: only-2


El enfoque de ejecutar diff -qr old/ new/ tiene un inconveniente importante: puede perder archivos en directorios recién creados. Por ejemplo, en el ejemplo siguiente, el archivo data/pages/playground/playground.txt no está en la salida de diff -qr old/ new/ mientras que el directorio data/pages/playground/ is (busque playground.txt en su navegador rápidamente comparar). También publiqué la siguiente solución en Unix & Linux Stack Exchange , pero también la copiaré aquí:

Para crear una lista de archivos nuevos o modificados mediante programación, la mejor solución que podría encontrar es usar rsync , sort y uniq :

(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq

Permítanme explicar con este ejemplo: queremos comparar dos lanzamientos de dokuwiki para ver qué archivos se cambiaron y cuáles se crearon recientemente.

Buscamos los tars con wget y los extraemos en los directorios old/ y new/ :

wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1 mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1

Ejecutar rsync one way puede perder los archivos recién creados, como lo muestra aquí la comparación de rsync y diff:

rsync -rcn --out-format="%n" old/ new/

produce el siguiente resultado:

VERSION doku.php conf/mime.conf inc/auth.php inc/lang/no/lang.php lib/plugins/acl/remote.php lib/plugins/authplain/auth.php lib/plugins/usermanager/admin.php

Ejecutar rsync solo en una dirección pierde los archivos recién creados y al revés perdería los archivos eliminados, compare la salida de diff:

diff -qr old/ new/

produce el siguiente resultado:

Files old/VERSION and new/VERSION differ Files old/conf/mime.conf and new/conf/mime.conf differ Only in new/data/pages: playground Files old/doku.php and new/doku.php differ Files old/inc/auth.php and new/inc/auth.php differ Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ

Ejecutar rsync en ambos sentidos y ordenar la salida para eliminar duplicados revela que los data/pages/playground/ del directorio data/pages/playground/ y el archivo data/pages/playground/playground.txt se perdieron inicialmente:

(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq

produce el siguiente resultado:

VERSION conf/mime.conf data/pages/playground/ data/pages/playground/playground.txt doku.php inc/auth.php inc/lang/no/lang.php lib/plugins/acl/remote.php lib/plugins/authplain/auth.php lib/plugins/usermanager/admin.php

rsync se ejecuta con estos argumentos:

  • -r para "consultar en directorios",
  • -c también para comparar archivos de tamaño idéntico y solo "omitir en función de la suma de comprobación, no de mod-time & size",
  • -n para "realizar una ejecución de prueba sin realizar cambios", y
  • --out-format="%n" para "generar actualizaciones usando el FORMATO especificado", que es "% n" aquí solo para el nombre del archivo

La salida (lista de archivos) de rsync en ambas direcciones se combina y clasifica mediante la sort , y esta lista clasificada se condensa eliminando todos los duplicados con uniq


En mi sistema Linux para obtener solo los nombres de archivos

diff -q /dir1 /dir2|cut -f2 -d'' ''


Si desea obtener una lista de archivos que están solo en un directorio y no sus subdirectorios y solo sus nombres de archivo:

diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n ''s/[^:]*: //p''

Si desea hacer una lista recursiva de todos los archivos y directorios que son diferentes con sus rutas completas:

diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n ''s/://p'' | awk ''{print $3"/"$4}''

De esta manera puedes aplicar diferentes comandos a todos los archivos.

Por ejemplo, podría eliminar todos los archivos y directorios que están en dir1 pero no dir2:

diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n ''s/://p'' | awk ''{print $3"/"$4}'' xargs -I {} rm -r {}


También puedes usar rsync

rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out


rsync -rvc --delete --size-only --dry-run source dir target dir