Gemeinsame Unterverzeichnisnamen zwischen zwei verschiedenen Verzeichnissen identifizieren und löschen

Gemeinsame Unterverzeichnisnamen zwischen zwei verschiedenen Verzeichnissen identifizieren und löschen

Ich habe zwei Verzeichnisse dir1und , dir2die Hunderte von Unterverzeichnissen bei haben depth 1. Ich brauche nur Informationen zu den Unterverzeichnisnamen, die zwischen dir1und gemeinsam sind, dir2und lösche sie systematisch aus dir2. Ich muss keine Dateien oder Dateiinhalte vergleichen. Durchführen

diff -qr dir_one dir_two | sort

erzeugt auch die Dateinamen, was mich im Moment nicht interessiert.

Antwort1

Für Ihren Anwendungsfall können Sie Folgendes vermeiden:identifizierendie gemeinsamen Verzeichnisse, da rm -rfnicht vorhandene Verzeichnisse einfach ignoriert werden.

Es reicht also,find alleVerzeichnisse in dir1und löschen Sie sie aus dir2:

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 rm -rf --

Einige Erklärungen. Standardmäßig findwerden alle Verzeichnisse mit dem vollständigen Pfad gedruckt dir1. Wir drucken also -printfnur den Dateinamen ohne führende Verzeichnisse (%f) und den anderen Pfad „dir2“, den wir löschen möchten. Außerdem beenden wir den String mit dem Nullbyte „\0“, anstatt eine Zeilenumbruchoption zu verwenden, xargdie -0das Ganze in Bezug auf Dateinamen mit Leerzeichen sicher macht. Dann xargswird stdin gelesen und der Befehl ausgeführt rm, indem alle Strings als Argumente hinzugefügt werden.

Beachten Sie, dass Sie vor dem eigentlichen Löschen Ihre Befehlszeile testen können, indem Sie hinzufügen, echodass nur die rmBefehle gedruckt werden sollen:

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 echo rm -rf --

NurListedie allgemeinen Verzeichnisse, die Sie lsstattdessen verwenden könnten rm(fügen Sie 2>/dev/null hinzu, um nicht vorhandene zu ignorieren):

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 -r ls -d -- 2>/dev/null

Antwort2

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) <( cd dir2 && find -maxdepth 1 -type d | sort ) | ( cd dir2 && xargs rm -rf )

mit Zeilenumbrüchen zur besseren Lesbarkeit:

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) \
           <( cd dir2 && find -maxdepth 1 -type d | sort ) \
                | ( cd dir2 && xargs rm -rf )

Erläuterung

find -maxdepth 1 -type d

Listet nur Verzeichnisse ohne Unterverzeichnisse auf.

cd dir1 && find -maxdepth 1 -type d | sort

Wechseln Sie zuerst zum Verzeichnis und listen Sie dann die Verzeichnisse auf.

<( ... )

Prozesssubstitution.

comm -1 -3 <( ... ) <( ... )

Nehmen Sie die erste und die zweite Eingabe und drucken Sie Zeilen, die für die zweite Eingabe eindeutig sind. Dadurch werden tatsächlich Verzeichnisse gedruckt, die sich in befinden, dir2aber nicht in dir1.

... | ( cd dir2 && xargs rm -rf )

Ändern Sie das Arbeitsverzeichnis, um dir2es dann mit der Ausgabe des vorherigen Befehls als Argumente auszuführen rm -rf. Dadurch werden tatsächlich die Verzeichnisse gelöscht, die sich in befinden, dir2aber nicht in dir1.

Testen Sie zuerst, indem Sie das Rohr entfernen xargsund den Ausgang überprüfen.

Antwort3

find dir1 dir2 -maxdepth 2 | egrep '/' | xargs --max-args 1 basename | sort | uniq -c  | egrep -v '^      1 ' | while read n de ; do echo rm -rfv dir2/$de ; done

Entfernen Sie das Echo, wenn es korrekt ist.

verwandte Informationen