![Gemeinsame Unterverzeichnisnamen zwischen zwei verschiedenen Verzeichnissen identifizieren und löschen](https://rvso.com/image/97237/Gemeinsame%20Unterverzeichnisnamen%20zwischen%20zwei%20verschiedenen%20Verzeichnissen%20identifizieren%20und%20l%C3%B6schen.png)
Ich habe zwei Verzeichnisse dir1
und , dir2
die Hunderte von Unterverzeichnissen bei haben depth 1
. Ich brauche nur Informationen zu den Unterverzeichnisnamen, die zwischen dir1
und gemeinsam sind, dir2
und 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 -rf
nicht vorhandene Verzeichnisse einfach ignoriert werden.
Es reicht also,find
alleVerzeichnisse in dir1
und 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 find
werden alle Verzeichnisse mit dem vollständigen Pfad gedruckt dir1
. Wir drucken also -printf
nur 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, xarg
die -0
das Ganze in Bezug auf Dateinamen mit Leerzeichen sicher macht. Dann xargs
wird 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, echo
dass nur die rm
Befehle 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 ls
stattdessen 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.
<( ... )
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, dir2
aber nicht in dir1
.
... | ( cd dir2 && xargs rm -rf )
Ändern Sie das Arbeitsverzeichnis, um dir2
es 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, dir2
aber nicht in dir1
.
Testen Sie zuerst, indem Sie das Rohr entfernen xargs
und 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.