Wie entferne ich alle Dateien in einem Ordner mit Ausnahme einiger angegebener Dateien?

11

Ich möchte alle Dateien in einem Verzeichnis entfernen, während nur einige angegebene Dateien übrig bleiben. Sie haben namentlich nichts gemeinsam. Wie könnte ich das erreichen?

Die Dateinamen, die ich behalten möchte, sind beispielsweise:

file_1.png, another_file.jpg,some_music.mp3

AGamePlayer
quelle

Antworten:

14

Wenn Sie bash verwenden:

shopt -s extglob
rm -- !(file1|file2|file3)

Die erste Zeile aktiviert nur den erweiterten Mustervergleich, und danach verwenden wir einen davon:

!(pattern-list) passt zu etwas anderem als einem der angegebenen Muster

und die Musterliste ist eine Liste von einem oder mehreren Mustern, die durch a getrennt sind |.


Oder mit zsh

setopt extendedglob
rm -- ^(file1|file2)

Oder tragbarer mit find:

find . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -v {} +
jimmij
quelle
3
Es kann nützlich sein, anzugeben, wie das optionale Shell-Verhalten zurückgegeben wird ( shopt -u extglob).
Geedoubleya
7

Erstellen Sie ein Unterverzeichnis tmp, verschieben Sie alle Dateien, die Sie behalten möchten, in dieses Verzeichnis und führen Sie anschließend eine Datei durch rm -f *. Das tmpVerzeichnis wird davon nicht betroffen .

Danach machen Sie einfach:

mv tmp/* .
rmdir tmp

(Angenommen, keine der von Ihnen verschobenen Dateien beginnt mit einem Punkt).

Dies ist einer der wenigen Fälle, in denen es sinnvoll ist, die Maus und einen Dateibrowser wie Nautilus zu verwenden, in denen Sie tatsächlich Ctrlauf die wenigen Dateien klicken können, die Sie behalten möchten, und dann das Menü verwenden: Edit -> Invert Selectionum die anderen Dateien abzurufen und diese dann zu löschen .

Anthon
quelle
Das Verschieben von Dateien in das tmp-Verzeichnis klingt gut. Jedenfalls muss ich das mit der Kommandozeile machen. Vielen Dank!
AGamePlayer
3
@AwQiruiGuo Der tmp hat den Vorteil, dass er zuerst die Dateien in zwei Sätze aufteilt, bevor er unwiderruflich diejenigen entfernt, die Sie nicht möchten. Sie können also eine ausführen, lsum festzustellen, ob Sie keine der Dateien verpasst haben, die Sie beibehalten möchten.
Anthon
2

Fügen Sie die Namen der Dateien, die Sie behalten möchten, zu einer Textdatei hinzu, eine pro Zeile. Diese Datei sollte sich nicht im Verzeichnis befinden oder Sie sollten auch ihren Namen hinzufügen.

Wenn der Name Ihres Verzeichnisses foo und der Name der Datei bar ist , gehen Sie wie folgt vor.

find foo -type f -print0|grep -vzZ -f bar|xargs -0 rm

Dies bewirkt Folgendes:

  1. find -type fsucht nach den Namen aller Dateien in foo und seinen Unterverzeichnissen und druckt sie in STDOUT aus. Mit der Option werden -print0die Dateinamen mit NUL-Bytes begrenzt.
  2. grep -v -f barschließt alle Dateinamen aus, die mit einer Zeile in der Leiste übereinstimmen . Mit Option -zbehandelt es seine Eingabe als eine Reihe von Zeilen, die durch NUL-Byte begrenzt sind, mit Option begrenzt -Zes seine Ausgabe mit einem NUL-Byte.
  3. xargs rmruft rmwiederholt auf, um die Dateien zu löschen. Mit der Option -0wird die Eingabe als eine Reihe von Zeilen behandelt, die durch das NUL-Byte begrenzt sind.

Dies funktioniert mit Dateinamen, die Leerzeichen enthalten.

Mathias Weidner
quelle
Dies funktioniert nicht, da Dateinamen Zeilenumbrüche enthalten können.
Anthon
@Anthon änderte die Optionen von find, grep, xargs, um mit Dateinamen umzugehen, die Leerzeichen enthalten, einschließlich newline
Mathias Weidner
Wenn Sie verwenden möchten, findwürde ich lieber tunfind . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -vi {} +
jimmij