Réponses:
Voici la solution simple que vous devriez probablement utiliser:
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
L' .keep
extension n'a rien de spécial , cela permet simplement d'éviter que le nom du fichier ne se termine temporairement .gif
.
Si vous ne devez pas renommer le fichier (et qu'il existe des situations de script dans lesquelles cela est important):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
Ou vous pouvez l'écrire plus court comme ceci:
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
Vous préférerez peut-être utiliser à la find
place; il est très puissant, vous pouvez le considérer plus lisible, et il vaut mieux les poignées des noms de fichiers étranges avec des personnages comme *
en eux .
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
J'ai utilisé l' -not
opérateur pour plus de lisibilité, mais si la conformité POSIX est importante - si vous n'utilisez pas GNU Find ou si c'est pour un script que vous souhaitez redistribuer à d'autres ou exécuter sur différents systèmes - vous devez utilisez l' !
opérateur à la place:
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
Un avantage pratique find
est que vous pouvez facilement modifier la commande pour tenir compte de la casse, afin de rechercher et de supprimer les fichiers portant l’extension suivante .GIF
:
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
Veuillez noter que j'ai utilisé -iname
à la place de -name
pour le modèle de recherche *.gif
mais je ne l' ai pas utilisé pour filename.gif
. Vraisemblablement, vous savez exactement comment votre fichier s'appelle et -iname
correspondra à une casse supplémentaire non seulement dans l' extension , mais n'importe où dans le nom du fichier.
Toutes ces solutions suppriment uniquement les fichiers résidant immédiatement dans le répertoire en cours . Ils ne suppriment pas les fichiers ne figurant pas dans le répertoire en cours, ni les fichiers résidant dans des sous-répertoires du répertoire en cours.
Si vous souhaitez supprimer des fichiers situés partout dans le répertoire actuel (c'est-à-dire y compris dans des sous-répertoires et des sous-répertoires de ces sous-répertoires, et ainsi de suite - fichiers contenus dans le répertoire actuel ou l'un de ses descendants), utilisez find
sans maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
Soyez prudent avec ça!
Vous pouvez également définir d'autres valeurs avec -maxdepth
. Par exemple, pour supprimer des fichiers du répertoire actuel et de ses enfants et petits-enfants, mais pas plus profondément:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
Assurez-vous juste de ne jamais mettre en -delete
premier, avant les autres expressions! Vous verrez que j'ai toujours mis -delete
à la fin. Si vous le mettez au début, il sera évalué en premier et tous les fichiers sous .
(y compris les fichiers ne se terminant pas .gif
et les fichiers dans les sous-sous-sous-répertoires profonds de .
) seront supprimés!
Pour plus d' informations , consultez les pages de manuel pour bash
et sh
et pour les commandes utilisées dans ces exemples: mv
, rm
, [
et (surtout) find
.
find
, qui est très polyvalent.
find
gérer les noms de fichiers étranges avec *
en eux mieux que la boucle for? La boucle for traite les fichiers avec *
fin, parce que vous avez utilisé des guillemets doubles.
Si vous utilisez bash
(le shell par défaut), l' extglob
option shell vous permet d'utiliser une syntaxe de correspondance de motif étendue. Pour l'activer, utilisez la shopt
commande intégrée:
shopt -s extglob
(J'inclus cette ligne dans mon .bashrc
dossier.)
Entre autres choses, il accorde un accès à l’ !()
opérateur, qui correspond à n’importe quel modèle ne se trouvant pas à l’intérieur des parenthèses. Pour votre but:
rm !(filename).gif
Plus d'informations sont disponibles dans la section man bash
"Correspondance de modèle".
extglob
doit être activée, mais rien ne se passe s'il est désactivé (dans ce cas, cela ne fonctionne tout simplement pas). Et il semble être activé par défaut, même si je n'ai shopt -s extglob
dans aucun de mes fichiers de configuration (ou globaux). S'il existe une explication simple de la raison pour laquelle cela fonctionne pour moi immédiatement, vous pouvez l'ajouter à cette réponse; ou je peux poster une nouvelle question.
Ouvrez un terminal avec Ctrl+ Alt+ Tet tapez:
find . -type f -name "*.gif" -and -not -name "filename.gif" -exec rm -vf {} \;
La différence entre -delete
et -exec rm -vf {} \;
est qu'avec la deuxième option, vous pourrez voir quels fichiers ont été supprimés, à cause du -v
drapeau. C'est quelque chose qui ne peut pas être fait avec l' -delete
option. ( -name -delete
imprimera les noms de fichiers, mais rm
avec -v
indique si chaque fichier a été supprimé avec succès .)
Il y a la GLOBIGNORE
variable. De 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.
Ainsi, un moyen simple consiste à définir GLOBGINORE
le nom de fichier en question:
$ 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
Donc, dans votre cas:
GLOBIGNORE=filename.gif; rm *.gif
Bien sûr, puisque GLOBIGNORE
contient des modèles, vous pouvez l’utiliser chaque fois que vous souhaitez exclure un modèle:
$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png
Un avantage (?!) GLOBIGNORE
Est que ce paramètre exclut .
et..
ne correspond pas automatiquement et permet 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.
Donc, un moyen simple de supprimer tous les fichiers et dossiers d’un répertoire:
GLOBIGNORE=.; rm -r *
Les *
noms de fichiers correspondant aux noms commençant par .
, étant GLOBIGNORE
activés dotglob
, mais ne correspondant pas .
ou ..
, de sorte que vous n'affecterez pas le répertoire parent de cette façon.