it-swarm.com.de

diff, um nur die Dateinamen auszugeben

Ich versuche, einen Linux-Befehl auszuführen, der zwei Verzeichnisse rekursiv vergleicht und nur die Dateinamen der verschiedenen ausgibt. Dies schließt alles ein, was in einem Verzeichnis vorhanden ist und nicht im anderen oder umgekehrt, und Textunterschiede.

222
barfoon

Von der Diff-Manpage:

-q Nur melden, ob sich die Dateien unterscheiden, nicht die Details der Unterschiede.
-r Wenn Sie Verzeichnisse vergleichen, vergleichen Sie rekursiv alle gefundenen Unterverzeichnisse.

Beispielbefehl:

diff -qr dir1 dir2

Beispielausgabe (abhängig vom Gebietsschema):

$ 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
337
John Kugelman

Sie können auch rsync verwenden

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

Wenn Sie eine Liste von Dateien erhalten möchten, die sich nur in einem Verzeichnis und nicht in ihren Unterverzeichnissen und nur in ihren Dateinamen befinden:

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

Wenn Sie alle Dateien und Verzeichnisse, die unterschiedlich sind, mit ihren vollständigen Pfaden rekursiv auflisten möchten:

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

Auf diese Weise können Sie auf alle Dateien unterschiedliche Befehle anwenden.

Zum Beispiel könnte ich alle Dateien und Verzeichnisse entfernen, die sich in dir1, aber nicht in dir2 befinden:

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

Der Ansatz des Laufens diff -qr old/ new/ hat einen großen Nachteil: Möglicherweise fehlen Dateien in neu erstellten Verzeichnissen. Z.B. im Beispiel unterhalb der Datei data/pages/playground/playground.txt ist nicht in der Ausgabe von diff -qr old/ new/ während das Verzeichnis data/pages/playground/ is (suche nach playground.txt in deinem Browser, um schnell zu vergleichen). Ich habe auch die folgende Lösung gepostet nter Unix & Linux Stack Exchange , aber ich werde sie auch hier kopieren:

Um eine Liste mit neuen oder geänderten Dateien programmgesteuert zu erstellen, verwende ich am besten rsync , sort und uniq :

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

Lassen Sie mich anhand dieses Beispiels erklären: Wir möchten zwei DokuWiki-Versionen vergleichen, um festzustellen, welche Dateien geändert und welche neu erstellt wurden.

Wir holen die Teere mit wget und extrahieren sie in die Verzeichnisse old/ und 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

Wenn Sie rsync auf eine Weise ausführen, werden möglicherweise neu erstellte Dateien übersehen, wie der Vergleich von rsync und diff hier zeigt:

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

ergibt folgende Ausgabe:

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

Wenn Sie rsync nur in einer Richtung ausführen, werden die neu erstellten Dateien übersehen, und in der anderen Richtung werden gelöschte Dateien übersehen. Vergleichen Sie die Ausgabe von diff:

diff -qr old/ new/

ergibt folgende Ausgabe:

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

Wenn Sie rsync in beide Richtungen ausführen und die Ausgabe sortieren, um Duplikate zu entfernen, wird das Verzeichnis data/pages/playground/ und die Datei data/pages/playground/playground.txt wurden anfangs verpasst:

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

ergibt folgende Ausgabe:

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 wird mit folgenden Argumenten ausgeführt:

  • -r um "in Verzeichnisse zurückzukehren",
  • -c um auch Dateien mit identischer Größe zu vergleichen und nur "Überspringen basierend auf Prüfsumme, nicht Mod-Zeit & Größe",
  • -n, um "einen Probelauf ohne Änderungen durchzuführen", und
  • --out-format="%n" auf "Aktualisierungen mit dem angegebenen FORMAT ausgeben", hier nur für den Dateinamen "% n"

Die Ausgabe (Liste der Dateien) von rsync in beide Richtungen wird kombiniert und mit sort sortiert. Diese sortierte Liste wird dann verdichtet, indem alle Duplikate mit uniq entfernt werden.

9
iolsmit

Auf meinem Linux-System bekommen nur die Dateinamen

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