Comment «rm» ou «mv» une gamme de fichiers tels que file01.txt, file02.txt… file85.txt

23

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.


la source
Une question presque identique a été répondue ici: stackoverflow.com/questions/25049411/…
arielf

Réponses:

38

Vous devez utiliser l'expansion d'accolade de bash:

rm file{08..13}.txt

Cela supprimera les fichiers file08de file13, 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 correspondre file08à file13:

rm file0[8-9].txt file1[0-3].txt
heemayl
la source
5
l'expansion d'accolade est également utile avec des virgules, comme pour mv foo.{txt,md}orcp foo.txt{,.bak}
Kos
2

Certains shells, tels que le défaut d'Ubuntu /bin/sh(qui est dash) ou mkshn'ont pas d'extension d'accolade, ou en 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 printfpour 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 à remplacer echopar rmou 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 cela est assez portable - fonctionne avec dash, ksh, mksh, aussi bash. Dans le cas de kshet bashnous pouvons également utiliser c-style for loop syntax (but not in case ofmksh ordash`):

$ 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 bashle cas de, printfprend en charge l'impression sur variable, et donc nous pourrions faire printf -v num "%.2d" "$i"au lieu d'utiliser la substitution de commandes.

Sergiy Kolodyazhnyy
la source