web-dev-qa-db-fra.com

Comment ajouter des zéros non significatifs pour for-loop in shell?

J'ai un numéro de base pour loop qui incrémente la variable num de 1 à chaque itération ...

for (( num=1; num<=5; num++ ))
do
 echo $num
done

Quelles sorties:

1
2
3
4
5

J'essaie de le faire produire la sortie (ajouter un zéro à gauche avant $ num):

01
02
03
04
05

Sans faire:

echo 0$num
117
Bruce Blacklaws

Utilisez la syntaxe suivante:

$ for i in {01..05}; do echo "$i"; done
01
02
03
04
05

Si vous voulez utiliser printf, rien ne vous empêche de mettre son résultat dans une variable pour une utilisation ultérieure:

$ foo=$(printf "%02d" 5)
$ echo "${foo}"
05

Avertissement: Cela ne fonctionne que dans >=bash-4.

188
Adrian Frühwirth

seq -w détectera la largeur et la normalisera.

for num in $(seq -w 01 05); do
    ...
done

Apparemment, cela ne fonctionne pas sur les dernières versions d'iOS. Vous pouvez donc installer macports et utiliser sa version de seq, ou vous pouvez définir le format de manière explicite:

seq -f '%02g' 1 3
    01
    02
    03

Mais étant donné la laideur des spécifications de format pour un problème aussi simple, je préfère la solution proposée par Henk et Adrian, qui utilise uniquement Bash. Apple ne peut pas tout gâcher car il n'y a pas de version "unix" générique de Bash:

echo {01..05}

Ou:

for number in {01..05}; do ...; done
43
piojo

Utilisez la commande printf pour obtenir 0 padding:

printf "%02d\n" $num

Votre boucle sera comme ça:

for (( num=1; num<=5; num++ )); do printf "%02d\n" $num; done
01
02
03
04
05
28
anubhava

Je ne suis pas intéressé par la sortie à l'écran (c'est pour cela que printf est principalement utilisé, non?). La variable $ num va être utilisée comme paramètre pour un autre programme, mais laissez-moi voir ce que je peux faire avec cela.

Vous pouvez toujours utiliser printf:

for num in {1..5}
do
   value=$(printf "%02d" $num)
   ... Use $value for your purposes
done
15
David W.

À partir de la version 4.0, vous pouvez utiliser Expansion de l'accolade avec des chaînes de longueur fixe. Voir ci-dessous pour l'annonce originale.

Il fera exactement ce dont vous avez besoin et ne nécessite rien d’extérieur à Shell.

$ echo {01..05}
01 02 03 04 05

for num in {01..05}
do
  echo $num
done
01
02
03
04
05

CHANGEMENTS, release bash-4.0, section

Ceci est une description succincte des nouvelles fonctionnalités ajoutées à bash-4.0 depuis la publication de bash-3.2.

. . .

z. Le développement d'accolade permet maintenant le remplissage à zéro des valeurs numériques étendues et ajoutera le nombre approprié de zéros pour garantir que toutes les valeurs contiennent le même nombre de chiffres.

8
Henk Langeveld

pourquoi pas printf '%02d' $num? Voir help printf pour cette commande interne bash.

6
Benoit

Juste une remarque: j'ai eu différents comportements sur différentes versions de bash:

  • version 3.1.17 (1) -release- (x86_64-suse-linux) et
  • Version 4.1.17 (9) -release (x86_64-unknown-cygwin))

pour l'ancien (3.1) for nn in (00..99) ; do ... fonctionne mais for nn in (000..999) ; do ... ne fonctionne pas les deux fonctionnera sur la version 4.1; n'a pas testé le comportement printf (bash --version a donné les informations de version)

À la vôtre, Jan

1
jd_doubley