web-dev-qa-db-fra.com

Comment "rm" ou "mv" une plage de fichiers tels que file01.txt, file02.txt ... file85.txt

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.

22
Cesare Fusari

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
37
heemayl

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 ofmkshordash`):

$ 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.

2