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?

Antworten:


23

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

shopt -s extglob
echo rm -rf !(A)

(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 {} \;

10

Wie wäre es mit:

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

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


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 .


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 ...



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.


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

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.



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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.