Antworten:
Hier ist die einfache Lösung, die Sie wahrscheinlich verwenden sollten:
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
Es gibt nichts Besonderes an der .keep
Erweiterung, dies macht es nur so, dass der Dateiname vorübergehend nicht endet .gif
.
Wenn Sie die Datei nicht umbenennen müssen (und es Skriptsituationen gibt , in denen dies wichtig ist):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
Oder du kannst es kürzer schreiben:
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
Sie können es vorziehen, find
stattdessen zu verwenden ; Es ist sehr mächtig, man könnte es für lesbarer halten und es behandelt seltsame Dateinamen mit Zeichen wie *
in ihnen besser .
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
Ich habe den -not
Operator aus Gründen der Lesbarkeit verwendet, aber wenn die POSIX- Konformität wichtig ist - wenn Sie GNU find nicht verwenden oder wenn dies für ein Skript gilt, das Sie an andere weitergeben oder auf einer Vielzahl von Systemen ausführen möchten - sollten Sie dies tun Verwenden Sie !
stattdessen den Operator:
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
Eine praktische Sache find
ist, dass Sie den Befehl für Groß- und Kleinschreibung leicht ändern können, so dass er Dateien mit folgenden Erweiterungen findet und löscht .GIF
:
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
Bitte beachten Sie, dass ich -iname
anstelle von -name
für das Suchmuster verwendet habe, es *.gif
aber nicht verwendet habe filename.gif
. Vermutlich wissen Sie genau, wie Ihre Datei heißt, und -iname
die alternative Groß- und Kleinschreibung wird nicht nur in der Erweiterung , sondern an einer beliebigen Stelle im Dateinamen berücksichtigt.
Alle diese Lösungen löschen nur Dateien, die sich unmittelbar im aktuellen Verzeichnis befinden . Sie löschen keine Dateien, die nicht im aktuellen Verzeichnis enthalten sind, und sie löschen keine Dateien, die sich in Unterverzeichnissen des aktuellen Verzeichnisses befinden.
Wenn Sie Dateien löschen möchten, die sich überall im aktuellen Verzeichnis befinden (dh auch in Unterverzeichnissen und Unterverzeichnissen dieser Unterverzeichnisse usw. - Dateien, die sich im aktuellen Verzeichnis oder in einem seiner Nachkommen befinden), verwenden Sie find
ohne maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
Sei vorsichtig damit!
Sie können mit auch andere Werte einstellen -maxdepth
. Zum Beispiel, um Dateien im aktuellen Verzeichnis und seinen Kindern und Enkelkindern zu löschen, aber nicht tiefer:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
Stellen Sie nur sicher, dass Sie niemals -delete
zuerst vor den anderen Ausdrücken stehen! Du wirst sehen, ich habe immer -delete
am Ende gesetzt. Wenn Sie es an den Anfang stellen, wird es zuerst ausgewertet, und alle Dateien unter .
(einschließlich Dateien, die nicht auf enden, .gif
und Dateien in tiefen Unterverzeichnissen von ... .
) werden gelöscht!
Weitere Informationen finden Sie in den Handbuchseiten für bash
und sh
und für die Befehle in diesen Beispielen verwendet: mv
, rm
, [
, und (vor allem) find
.
find
, die sehr vielseitig einsetzbar ist.
find
mit seltsamen Dateinamen *
besser um als mit der for-Schleife? Die for-Schleife behandelt Dateien mit *
fine, da Sie doppelte Anführungszeichen verwendet haben.
Wenn Sie bash
(die Standard-Shell) verwenden, extglob
können Sie mit der Shell-Option eine erweiterte Pattern-Matching-Syntax verwenden. Verwenden Sie zum shopt
Aktivieren den integrierten Befehl:
shopt -s extglob
(Ich füge diese Zeile in meine .bashrc
Datei ein.)
Unter anderem wird dem !()
Bediener der Zugriff gewährt , der mit jedem Muster übereinstimmt, das sich nicht innerhalb der Parens befindet. Für Ihren Zweck:
rm !(filename).gif
Weitere Informationen finden Sie man bash
unter "Pattern Matching".
extglob
die aktiviert werden muss, aber nichts Schlimmes passiert, wenn es deaktiviert ist (in diesem Fall funktioniert dies einfach nicht). Und es scheint standardmäßig aktiviert zu sein, obwohl ich shopt -s extglob
keine meiner (oder der globalen) Konfigurationsdateien habe. Wenn es eine einfache Erklärung dafür gibt, warum es bei mir standardmäßig funktioniert, können Sie es zu dieser Antwort hinzufügen. oder ich poste eine neue Frage.
Öffne ein Terminal mit Ctrl+ Alt+ Tund tippe:
find . -type f -name "*.gif" -and -not -name "filename.gif" -exec rm -vf {} \;
Der Unterschied zwischen -delete
und -exec rm -vf {} \;
besteht darin, dass Sie mit der zweiten Option sehen können, welche Dateien aufgrund der -v
Markierung entfernt wurden. Das ist etwas, was mit dieser -delete
Option nicht möglich ist. ( -name -delete
Gibt die Dateinamen aus, zeigt jedoch rm
an -v
, ob jede Datei erfolgreich gelöscht wurde.)
Da ist die GLOBIGNORE
Variable. Von man bash
:
GLOBIGNORE
A colon-separated list of patterns defining the set of filenames
to be ignored by pathname expansion. If a filename matched by a
pathname expansion pattern also matches one of the patterns in
GLOBIGNORE, it is removed from the list of matches.
Eine einfache Möglichkeit besteht darin, nur GLOBGINORE
den fraglichen Dateinamen festzulegen:
$ touch {a,b,c,d}.png
$ echo *.png
a.png b.png c.png d.png
$ GLOBIGNORE=c.png
$ echo *.png
a.png b.png d.png
Also, in deinem Fall:
GLOBIGNORE=filename.gif; rm *.gif
Da es GLOBIGNORE
Muster enthält, können Sie es natürlich immer dann verwenden, wenn Sie ein Muster ausschließen möchten:
$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png
(?!) Ein Vorteil GLOBIGNORE
ist , dass Einstellung automatisch schließt .
und..
aus wird abgestimmt, und es ermöglicht dotglob
:
The GLOBIGNORE shell variable may be used to restrict the set of file‐
names matching a pattern. If GLOBIGNORE is set, each matching filename
that also matches one of the patterns in GLOBIGNORE is removed from the
list of matches. The filenames ``.'' and ``..'' are always ignored
when GLOBIGNORE is set and not null. However, setting GLOBIGNORE to a
non-null value has the effect of enabling the dotglob shell option, so
all other filenames beginning with a ``.'' will match. To get the old
behavior of ignoring filenames beginning with a ``.'', make ``.*'' one
of the patterns in GLOBIGNORE. The dotglob option is disabled when
GLOBIGNORE is unset.
So löschen Sie auf einfache Weise alle Dateien und Ordner in einem Verzeichnis:
GLOBIGNORE=.; rm -r *
Das *
stimmt mit den Dateinamen überein, die mit .
, da GLOBIGNORE
aktiviert dotglob
, beginnen , stimmt jedoch nicht mit .
oder überein ..
, sodass Sie das übergeordnete Verzeichnis nicht auf diese Weise beeinflussen.