Löschen aller Dateien in einem Ordner mit Ausnahme der Dateien X, Y und Z

17

Ich habe viele Dateien und Ordner in einem bestimmten Ordner und möchte alle löschen. Ich wollte jedoch die Dateien X, Y und Z behalten.

Gibt es eine Möglichkeit, wie ich etwas tun kann: rm * | but NOT grep | X or Y or Z

Amit
quelle
Ich nehme an, ich kann einen regulären Ausdruck verwenden, der dies erledigt.
Amit

Antworten:

16

Anstatt rm zu verwenden, ist es möglicherweise einfacher, find zu verwenden . Ein Befehl wie dieser löscht alles außer einer Datei mit dem genauen Namen 'file'.

find . \! -name 'file' -delete

Viele Versionen von sollten in der Lage sein, das Abgleichen von Globen und regulären Ausdrücken zu unterstützen.

Sie können auch die Ausgabe von find an rm leiten

find . \! -name '*pattern*' -print0 | xargs --null rm 
Zoredache
quelle
3
Auf diese Weise können Sie genau sehen, welche Dateien beim Entfernen von gelöscht werden und -deletewelche Dateien beim Entfernen von -deleteund von gespeichert werden \!.
Shawn J. Goff
1
Vorsicht, findist rekursiv! Alle Unterverzeichnisse, die nicht mit ' pattern ' übereinstimmen, werden ebenfalls gelöscht
Alexandre Holden Daly
Der Weg über xargs benötigt -depth, um zu verhindern, dass Verzeichnisse vor den darin enthaltenen Dateien gelöscht werden. Ich denke jedoch, dass rm auch keine Verzeichnisse entfernen wird.
Benutzer unbekannt
9

Verwenden von zsh mit setopt EXTENDED_GLOBdem ~Operator ( außer )

rm -- *~(x|y|z)

oder ^Operator (Verneinung):

rm -- ^(x|y|z)

Aber Sie sollten die Dateien wahrscheinlich stattdessen an einen anderen Ort verschieben und dann alles löschen. Es ist weitaus sicherer in Bezug auf Fingerabdrücke, z. B. wenn Sie zu früh auf die Eingabetaste drücken.

wnoise
quelle
5

In späteren Versionen von bash gibt es die extglobShell-Option, mit der Sie eine Syntax festlegen können, um das zu tun, was Sie möchten.

$ shopt -s extglob  # turn on extended globbing
$ rm !(X|Y|Z)

Zum Test, empfehle ich Ihnen zunächst ersetzen rmmit , echoum zu sehen , ob die Liste der Dateien gelöscht werden soll , was Sie erwarten.

camh
quelle
5
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r

Achtung: Führen Sie den Befehl aus. Wenn die zu löschenden Dateien die richtigen sind, führen Sie ihn erneut aus und löschen Sie das Hash-Zeichen "#".

Wenn die Dateinamen komplizierter sind, tun Sie dies

ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r

Schauen Sie sich die Ergebnisse noch einmal an und entfernen Sie dann das Hash-Zeichen.

Diese Version - wie in den Kommentaren vorgeschlagen - speichert einige Zeichen und sieht ein bisschen klarer aus.

ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r
ddeimeke
quelle
Eine vorgeschlagene Änderung von ddeimeke ist, das egrepArgument zu ändern"^(file1|filename2|f1le)$"
Michael Mrozek
Wenn Sie drei Dateien haben a, bund a bdas erste Programm wird gelöscht - wenn Sie ab in den grep Teil setzen: "^[ab]$" aund baber nicht a b, im Gegensatz zu nur Ihre Absichten. Der zweite Befehl macht dasselbe. Und der dritte auch. Sie sollten 'ls' in Skripten nicht verwenden, mit sehr, sehr seltenen Ausnahmen. Tu es einfach nicht.
Benutzer unbekannt
3

Verschieben Sie die Dateien, die Sie fernhalten möchten. Gehe eine Ebene höher und lösche den Ordner. Erstellen Sie den Ordner neu und verschieben Sie diese Dateien zurück.

Alex
quelle
Ich frage mich, warum das Minus? Es ist eigentlich einfacher und sicherer als alles, was von anderen vorgeschlagen wird: Sie können sich einfach nicht in den Fuß schießen, indem Sie ein Sonderzeichen im Dateinamen treffen.
alex
a) Sie verschieben Ihre Datei X um ein Verzeichnis nach oben, in dem sich eine Datei X befindet - stillschweigend gelöscht, verschwunden. b) Sie befinden sich in der obersten Ebene, in der kein 'Auf' vorhanden ist. c) Sie sind in Ihrem Hause, und haben nicht die Erlaubnis zu schreiben / home. Wenn Sie Ihre Ratschläge in ein Skript schreiben und es ohne Probleme testen und in einer solchen Situation verwenden - peng!
Benutzer unbekannt
2
a) Hey, habe ich gesagt, 'Dateien um eine Ebene nach oben verschieben'? Ich habe gesagt, bring sie weg. b) Also versuchst du alle Dateien zu entfernen /, heh? Nicht sehr praktisch. c) Es $HOMEist auch nicht wirklich praktisch , alle Dateien in Ihrem zu entfernen .
Alex
Du hast recht, es tut mir leid.
Benutzer unbekannt
0

Dies ist, was ich als .sh-Skript für einen OSX / MacOS-Abmelde-Hook eingerichtet habe, funktioniert gut genug.

#! /bin/bash
for dir in /PathToFolder/*
 do
    if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then 
      echo ${dir}
      sudo rm -R $dir user
      dscl . -delete $dir
    fi 
  done

exit 0
ICMP
quelle
0

Mit GNU-find können Sie den Schalter -delete verwenden, der auch leere Verzeichnisse entfernt:

 find tmp -not -name X -not -name Y -not -name Z -delete 
Benutzer unbekannt
quelle
Wenn X, Y oder Z ein Verzeichnis ist, werden auch die darin enthaltenen Dateien gelöscht. find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -deleteist eine Möglichkeit, dies zu umgehen.
Gilles 'SO - hör auf böse zu sein'
Da Ordner unter Unix Dateien sind (alles ist eine Datei), ist das vielleicht beabsichtigt. Die Frage lautet ausdrücklich: "Ich habe viele Dateien und Ordner in einem bestimmten Ordner und möchte alle löschen." - Wenn Sie Y ausschließen möchten, wissen Sie vielleicht, ob Y ein Verzeichnis ist oder nicht.
Benutzer unbekannt
Das wird am Ende des Löschen tmpals auch , wenn es keine waren X/ Y/ Zin ihm - Dateien. Beachten Sie !als Standardäquivalent von GNU -not( -deleteist auch eine GNU-Erweiterung)
Stéphane Chazelas
@ StéphaneChazelas: Aus der Frage, Löschen von Ordnern (alle von ihnen) ist, was gefragt wurde. Da der Knall maskiert werden muss, gebe ich lieber -not ein. Könnte vom deutschen Tastaturlayout abhängen, wo Backslash Alt-Gr benötigt.
Benutzer unbekannt