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 .keepErweiterung, 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, findstattdessen 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 -notOperator 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 findist, 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 -inameanstelle von -namefür das Suchmuster verwendet habe, es *.gifaber nicht verwendet habe filename.gif. Vermutlich wissen Sie genau, wie Ihre Datei heißt, und -inamedie 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 -deletezuerst vor den anderen Ausdrücken stehen! Du wirst sehen, ich habe immer -deleteam Ende gesetzt. Wenn Sie es an den Anfang stellen, wird es zuerst ausgewertet, und alle Dateien unter .(einschließlich Dateien, die nicht auf enden, .gifund Dateien in tiefen Unterverzeichnissen von ... .) werden gelöscht!
Weitere Informationen finden Sie in den Handbuchseiten für bashund shund für die Befehle in diesen Beispielen verwendet: mv, rm, [, und (vor allem) find.
find, die sehr vielseitig einsetzbar ist.
findmit 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, extglobkönnen Sie mit der Shell-Option eine erweiterte Pattern-Matching-Syntax verwenden. Verwenden Sie zum shoptAktivieren den integrierten Befehl:
shopt -s extglob
(Ich füge diese Zeile in meine .bashrcDatei 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 bashunter "Pattern Matching".
extglobdie 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 extglobkeine 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 -deleteund -exec rm -vf {} \;besteht darin, dass Sie mit der zweiten Option sehen können, welche Dateien aufgrund der -vMarkierung entfernt wurden. Das ist etwas, was mit dieser -deleteOption nicht möglich ist. ( -name -deleteGibt die Dateinamen aus, zeigt jedoch rman -v, ob jede Datei erfolgreich gelöscht wurde.)
Da ist die GLOBIGNOREVariable. 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 GLOBGINOREden 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 GLOBIGNOREMuster 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 GLOBIGNOREist , 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 GLOBIGNOREaktiviert dotglob, beginnen , stimmt jedoch nicht mit .oder überein .., sodass Sie das übergeordnete Verzeichnis nicht auf diese Weise beeinflussen.