Dadurch werden alle Ordner in ./myfolder
gelöscht außer dass ./myfolder/test2
und alle Inhalte bleiben erhalten:
find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete
Wie es funktioniert
find
startet einen Suchbefehl.-
./myfolder
weist find an, mit dem Verzeichnis./myfolder
zu beginnen und seine Inhalte. -
-mindepth 1
nicht mit./myfolder
übereinstimmen selbst, nur die Dateien und Verzeichnisse darunter. -
! -regex '^./myfolder/test2\(/.*\)?'
weist find an, auszuschließen (!
) jede Datei oder jedes Verzeichnis, das dem regulären Ausdruck^./myfolder/test2\(/.*\)?
entspricht .^
stimmt mit dem Beginn des Pfadnamens überein. Der Ausdruck(/.*\)?
entspricht entweder (a) einem Schrägstrich gefolgt von irgendetwas oder (b) gar nichts. -
-delete
weist find an, die übereinstimmenden (d. h. nicht ausgeschlossenen) Dateien zu löschen.
Beispiel
Stellen Sie sich eine Verzeichnisstruktur vor, die wie folgt aussieht:
$ find ./myfolder
./myfolder
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Wir können den find-Befehl ausführen (ohne -delete
), um zu sehen, was passt:
$ find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?'
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
Wir können überprüfen, ob dies funktioniert hat, indem wir uns die verbleibenden Dateien ansehen:
$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Bash verwenden:
shopt -s extglob
rm -r myfolder/!(test2)/
Beispiel:
$ tree myfolder/
myfolder/
├── test1
│ └── file1
├── test2
│ └── file2
└── test3
└── file3
$ echo rm -r myfolder/!(test2)
rm -r myfolder/test1 myfolder/test3
$ rm -r myfolder/!(test2)
$ tree myfolder/
myfolder/
└── test2
└── file2
1 directory, 1 file
tl;dr
find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
-exec echo rm -rf '{}' \;
Entfernen Sie Echo, wenn Sie mit der Liste der Dateien zufrieden sind.
Mit -mindepth 1
sorgt dafür, dass die Oberseite Verzeichnis ist nicht ausgewählt.
$ find ./myfolder -mindepth 1 -type d
./myfolder/test2
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Aber ein -not -name test2
wird nicht Vermeiden Sie Unterverzeichnisse innerhalb von test2
:
$ find ./myfolder -mindepth 1 -type d -not -name 'test2'
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Dazu brauchen Sie so etwas wie prune:
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Aber verwenden Sie nicht delete
, wie es depth
impliziert und das beginnt mit dem Löschen vom längsten Pfad:
$ find ./myfolder -depth -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test/a1/a2/a3
./myfolder/test/a1/a2
./myfolder/test/a1
./myfolder/test
Verwenden Sie entweder rm -rf
(Entfernen Sie den echo
wenn Sie tatsächlich löschen möchten):
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
rm -rf ./myfolder/test/a1
rm -rf ./myfolder/test/a1/a2
rm -rf ./myfolder/test/a1/a2/a3
Oder auch Verwenden Sie maxdepth
wenn Sie nur Verzeichnisse (und alles darin) löschen müssen (entfernen Sie die Datei echo
eigentlich löschen):
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
Ein -delete
wird immer noch fehlschlagen, wenn das Verzeichnis nicht leer ist:
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty