liste des fichiers numérotés dans une plage spécifique

15

J'ai un ensemble de fichiers dans un répertoire numéroté comme suit:

file1.txt
file2.txt
...
file30.txt
...

Maintenant, je voudrais exécuter une commande sur une gamme spécifique de fichiers, disons 18 à travers 31.

Jusqu'à présent, j'ai utilisé les moyens suivants,

trois arguments

command file1[8-9].txt file2[0-9].txt file3[0-1].txt

Supposons maintenant que je veux tous les autres numéros,

boucle

for i in `jot - 18 31 2`; do echo file${i}.txt; done | xargs command

cela semble être une boucle plus fiable (les espaces fonctionnent)

for i in `jot - 18 31 2`; do echo "\"file${i}.txt\" "; done | xargs command

mais il semble qu'il devrait y avoir un moyen plus simple de le faire. Je devine le La meilleure solution consiste à créer une fonction bash qui renverra l’ensemble des fichiers. la ligne de commande. Ensuite, je pourrais faire quelque chose comme,

command `filerange file 18 31`

Existe-t-il de meilleurs moyens ou suggestions pour le faire efficacement?

Je m'excuse d'avance si j'ai manqué cette même question a répondu ailleurs sur le web ou sur superuser.

milkypostman
la source
J'ai mis à jour ma question pour inclure une solution utilisant un for boucle qui permet des espaces dans les noms de fichiers en utilisant xargs. Cela semble fonctionner si vous n'avez pas bash 4. Si vous avez bash 4, alors utilisez certainement le développement de croisillons! Voir la réponse sélectionnée. Prise éhontée pour mettre à niveau Snow Leopard bash
milkypostman

Réponses:

23

Essaye ça:

for file in file{18..31}.txt

Il est connu comme une "expression de séquence" et fait partie de Bash expansion du corset fonctionnalité. Cela fonctionne dans Bash 3 et 4.

La fonctionnalité d'incrément est nouvelle pour Bash 4. Vous avez probablement Bash 3.x.

Dans Bash 4, vous pouvez faire:

$ for i in {1..6..2}; do echo $i; done
1
3
5

Mais dans Bash 3, vous devez le faire pour obtenir les mêmes résultats:

$ for ((i=1; i<=6; i+=2)); do echo $i; done

Le même formulaire incrémenté de un:

$ for ((i=1; i<=6; i++)); do echo $i; done

N'importe lequel des nombres peut être des variables ou des expressions. Cependant, dans une expression de séquence, les nombres doivent être des constantes

Voici un exemple d'utilisation de ce formulaire sur vos fichiers:

for ((i=18; i<=31; i++))
do
    echo "file${i}.txt"
done

Une autre nouvelle fonctionnalité des expressions de séquence dans Bash 4 est la possibilité d'inclure des zéros non significatifs. Ceci est utile si vous souhaitez créer (et utiliser) des fichiers numérotés pouvant être correctement triés.

Dans Bash 4:

touch file{001..010}.txt

créerait des fichiers nommés "fichier001.txt" par "fichier010.txt". Leurs noms seront triés dans l'ordre attendu. Sans les zéros au début, "fichier10.txt" serait trié avant "fichier1.txt".

Pour travailler avec les fichiers, vous pouvez utiliser la même syntaxe de zéro:

for file in file{001..010}.txt; do echo "$file"; done

Dans Bash 3, si vous avez besoin de zéros non significatifs, vous devez indiquer la valeur vous-même:

for i in {1..10}
do
    printf -v i '%03d' $i 
    echo "file${i}.txt"
done

le printf instruction va précéder la valeur de i avec des zéros non significatifs, de sorte que la largeur soit 3, par exemple ("4" devient "004").

Modifier:

La gestion des espaces dans les noms de fichiers est simple:

$ touch "space name "{008..018..3}" more spaces"
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces
$ for f in "space name "{008..018..3}" more spaces"; do mv "$f" "${f}.txt"; done
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt
Dennis Williamson
la source
Je vous remercie! Je ne sais pas où cela a été toute ma vie. La seule chose qui m’empêche de travailler est que l’incrément ne semble pas fonctionner dans la version OSX de bash. c'est-à-dire que je ne peux pas obtenir {1..10..2} travailler dans ma bash OSX.
milkypostman
Eh bien, c'est parce que Snow Leopard (pour une raison quelconque) utilise bash 3.1. C'est un problème de logiciel.
milkypostman
@milkypostman: fonctionnalité d'incrémentation et zéros non significatifs {01..10} sont nouveaux dans Bash 4. Vous avez probablement Bash 3.x. Si vous avez besoin de la fonctionnalité d'incrémentation ou si vous souhaitez utiliser des variables pour les limites de la plage, utilisez le formulaire suivant: for ((i=1; i<=10; i+=2} (ou i++ pour incrémenter de un). N'importe lequel des nombres peut être des variables ou des expressions. Ensuite, pour utiliser la valeur à l'intérieur du for boucle: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -v i '% 03d' $ i` qui préfixera la valeur de i avec des zéros en tête, la largeur est par exemple 3 ("4" devient "004")
Dennis Williamson
Dennis, y a-t-il moyen de mettre à jour votre solution pour inclure le formulaire alternatif. Être un commentaire, c'est un peu obscurcissant ce que je suis probablement supposé avoir.
milkypostman
@milkypostman: Voir ma réponse modifiée.
Dennis Williamson