Supposons que j'ai un tas de fichiers nommés de cette façon:
file01.txt file02.txt file03.txt ... file20.txt
et je veux exécuter une commande sur une gamme de ces fichiers.
Je sais que si je veux "rm" de "file05.txt" à "file09.txt" je peux faire:
rm file0[5-9].txt
mais comment puis-je "rm" une plage de file08.txt à file13.txt? J'ai essayé ce code
rm file[08-13].txt
et ça ne marche pas. Je pourrais exécuter cette commande:
rm file0[89].txt file1[0-3].txt
mais j'aimerais savoir si je peux le faire avec un seul argument plus raffiné à «rm» si c'est possible.
Réponses:
Vous devez utiliser l'expansion d'accolade de
bash
:Cela supprimera les fichiers
file08
defile13
, affichera un message d'erreur si un fichier est manquant.Réglez la gamme pour répondre à vos besoins.
Le problème avec l'opérateur de globalisation
[]
est qu'il traite chaque caractère / chiffre qu'il contient comme un seul jeton et ne prend donc en charge que la déclaration de plage en utilisant des chiffres simples.Si vous insistez pour utiliser
[]
, vous pouvez utiliser ce modèle plutôt laid pour correspondrefile08
àfile13
:la source
mv foo.{txt,md}
orcp foo.txt{,.bak}
Certains shells, tels que le défaut d'Ubuntu
/bin/sh
(qui estdash
) oumksh
n'ont pas d'extension d'accolade, ou en cas deksh
- l'expansion d'accolade ne peut pas utiliser de zéros remplis:Dans de tels cas, nous pouvons utiliser
printf
pour formater la partie numérique du nom de fichier, et utiliser une boucle while pour implémenter le comportement de boucle de type c (remarque à remplacerecho
parrm
ou ce que vous voulez):Et cela est assez portable - fonctionne avec
dash
,ksh
,mksh
, aussibash
. Dans le cas deksh
etbash
nous pouvons également utiliserc-style for loop syntax (but not in case of
mkshor
dash`):Notez que dans
bash
le cas de,printf
prend en charge l'impression sur variable, et donc nous pourrions faireprintf -v num "%.2d" "$i"
au lieu d'utiliser la substitution de commandes.la source