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 plage de ces fichiers.
Je sais que si vous voulez "rm" de "fichier05.txt" à "fichier09.txt", je peux le 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 lancer 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é pour "rm" si c'est possible.
Vous devez utiliser le développement d'accolade de bash
:
rm file{08..13}.txt
Cela supprimera les fichiers file08
en file13
et affichera un message d'erreur si un fichier est manquant.
Définissez la plage pour répondre à vos besoins.
Le problème avec l'opérateur globbing []
est qu'il traite chaque caractère/chiffre qu'il contient comme un seul jeton et qu'il ne prend donc en charge que la déclaration de plage utilisant des chiffres uniques.
Si vous insistez pour utiliser []
, vous pouvez utiliser ce modèle plutôt moche pour faire correspondre file08
à file13
:
rm file0[8-9].txt file1[0-3].txt
Certains shells, tels que /bin/sh
(qui est dash
) ou mksh
par défaut d'Ubuntu n'ont pas d'expansion d'accolade, ou dans le cas de ksh
- l'expansion d'accolade ne peut pas utiliser de zéros remplis:
$ ksh -c 'echo {05..13}'
5 6 7 8 9 10 11 12 13
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 un comportement de boucle de type c (remarque pour remplacer echo
par rm
ou faire ce que vous voulez):
$ i=5; while [ "$i" -le 10 ]; do num=$(printf "%.2d" "$i" ); echo "file$num.txt";i=$(($i+1)); done
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt
Et ceci est assez portable - fonctionne avec dash
, ksh
, mksh
, aussi bash
. Dans le cas de ksh
et bash
, nous pouvons également utiliser c-style for loop syntax (but not in case of
mkshor
dash`):
$ ksh -c 'for((i=5;i<11;i++)); do num=$(printf "%.2d" "$i" ); echo "file$num.txt";done'
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt
Notez que dans le cas de bash
, printf
prend en charge l’impression vers une variable. Nous pourrions donc utiliser printf -v num "%.2d" "$i"
au lieu d’utiliser la substitution de commande.