Löschen Sie alle Unterverzeichnisse bis auf eines

10

Angenommen, unter dem aktuellen Verzeichnis gibt es mehrere Unterverzeichnisse, und eines heißt A.

Wie lösche ich alle Unterverzeichnisse außer A mit Bash?

anon
quelle

Antworten:

23

Bash hat das Globbing verlängert (zuerst testen, dann das Echo entfernen):

shopt -s extglob
echo rm -rf !(A)
TheBonsai
quelle
(Bevor ich es vergesse - Sie können die Vervollständigung des CSH-Stils deaktivieren. In Bash3 gibt es einen Fehler beim Ignorieren! (. set + H
+1 Bash wenn voller Überraschungen! Manchmal sind sie so nett.
Aleksandr Levchuk
Wauw sehr schön! Funktioniert wie erwartet. Mit shopt | grep extSie können sehen, ob das Plugin aktiviert ist.
Gefahr89
14
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
dotjoe
quelle
10

Wie wäre es mit:

mv A /tmp/
rm * -rf
mv /tmp/A .

Dies vermeidet die "Knappheit" eines Tippfehlers in den anderen Befehlen.

Brent
quelle
1
+1 für das Vernünftige, anstatt zu hoffen, dass die Werkzeuge klug genug sind. Eines Nachts, als ich gerade Linux lernte, kopierte ich den Kernel nach / tmp, bevor ich meine erste Neukompilierung durchführte. es war nicht erfolgreich, aber es wurde das alte gelöscht, also sagte ich 'kein Schweiß, ich habe eine Kopie', nur um festzustellen, dass eine Mitternachts-Cron-Aufgabe es mit jeder Datei gelöscht hatte, die älter als eine Woche in / tmp war! Ich musste erneut kompilieren und diesmal richtig machen oder keinen Neustart für mich!
Javier
beste Antwort gepostet :)
Warren
3

Etwas wie

find . -type d -not -name A -exec rm -ir {} \;

sollte tun.

bearbeiten

Es sollte wirklich so sein

find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;

um ein findWiederauftreten unter A zu verhindern .

agnul
quelle
3
Dies würde jedoch auch alle Unterverzeichnisse unter A wie A / foo und A / bar entfernen, aber A / A beibehalten.
TCampbell
Cool! Fragen und Antworten werden von SO nach SF migriert ... aber meine obige Bearbeitung ging verloren ...
4.
Es sollte besser sein, maxdepth auszutauschen und Argumente wie folgt einzugeben: find. -maxdepth 1 -type d -not -name A -exec rm -ir {} \;
Spawnrider
1

Normalerweise mache ich das, indem ich einen ls-Befehl ausarbeite, der es zuerst richtig macht. Ich bin nicht auf einer Unix-Maschine, aber so etwas wie:

ls -lda "[^ A]"

Sobald Sie es richtig verstanden haben, leiten Sie es an einen Befehl weiter

ls -lda "[^ A]" | xargs rm -rf

Fühlen Sie sich frei, oben zu bearbeiten, wenn ich meinen regulären Ausdruck falsch habe ...

Tim Hoolihan
quelle
Sie sollten ls nicht analysieren: mywiki.wooledge.org/ParsingLs
Bis auf weiteres angehalten.
1

Wenn Sie flexibler, aber manuell sein möchten, können Sie Folgendes tun:

ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r

Auf diese Weise können Sie allgemeines Munging durchführen.

Joe Beda
quelle
1

Hier ist eine Möglichkeit. Seien Sie vorsichtig mit solchen Dingen, sie sind jedoch so mächtig, dass sie nur zum Guten oder Bösen verwendet werden können ...

find * -Typ d | grep -v "^ A" | xargs rm -rf
Don Branson
quelle
1

Verwenden Sie find nicht, wie einige Leute mit -exec und rm gezeigt haben, ohne -print0 zu übergeben und -0 an xargs zu übergeben. Dateinamen werden mit Leerzeichen oder Zeilenumbrüchen verwechselt:

$ mkdir 'foo foo'
$ mkdir foo$'\n'foo 
$ find . -type d -exec rm -ir {} \;
rm: cannot remove directory `.'
rm: remove directory `./foo\nfoo'? y
find: `./foo\nfoo': No such file or directory
rm: remove directory `./foo foo'? y
find: `./foo foo': No such file or directory

Verwenden Sie stattdessen find -print0 mit xargs -0, '-exec command {} +' oder -delete, wenn Ihr find dies unterstützt.

Kyle Brandt
quelle
1

Zusätzlich zum früheren Beispiel von:

find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

Sie können auch tun:

find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;

zu vermeiden, cd some/subdirzuerst müssen.

Lurchman
quelle