Comment puis-je accéder aux variables nommées séquentiellement par une boucle tout en restant dans la boucle?
Question
J'essaie de comprendre s'il est possible de créer un ensemble de variables numérotées en fonction d'une autre variable (à l'aide de eval) dans une boucle, puis de l'appeler avant la fin de la boucle.
A titre d'exemple, j'ai écrit un script appelé question (la première commande est de montrer quel est le contenu de la variable $ tab)
(23:32:12\[deco@S.Man)
[~/bin]$ listQpsk 40|grep -w [1-4]
40 SMANHUBAQPSK1 1 1344 1195 88
40 SMANHUBAQPSK1 2 1668 1470 88
40 SMANHUBAQPSK1 3 1881 1539 81
40 SMANHUBAQPSK1 4 1686 1409 83
(23:18:42\[deco@S.Man)
[~/bin]$ cat question
#!/usr/bin/bash
tab=`listQpsk 40|grep -w [1-4]`
seq=1
num=4
until [[ $seq -gt $num ]];do
eval count$seq=`echo "$tab"|grep -w $seq|awk '{print $5}'`
seq=$(($seq+1))
done
echo $count1
echo $count2
echo $count3
echo $count4
Quand je lance ceci, je reçois
(23:32:23\[deco@S.Man)
[~/bin]$ ./question
1195
1471
1538
1409
C'est exactement ce à quoi je m'attendais, mais existe-t-il un moyen de déplacer les commandes echo à l'intérieur de la boucle till de sorte qu'une partie de la boucle répète la valeur de la variable qui vient d'être créée. Quelque chose comme:
until [[ $seq -gt $num ]];do
eval count$seq=`echo "$tab"|grep -w $seq|awk '{print $5}'`
seq=$(($seq+1))
echo "$count$seq"
done
PS: Désolé si mon formatage est désactivé ... et que je ne connais que les annotations de Reddit.
La solution
Utiliser l'indirection:
until [[ $seq -gt $num ]];do
var="count$seq"
eval $var=$(echo "$tab"|awk -v seq=$seq '$3==seq {print $5}') # awk loves to do grep's job
let seq+=1 # another way
echo "${!var}" # indirection
done
Pas besoin d'un autre eval.
Autres conseils
Vous ne répondez pas exactement à votre question, mais ... saviez-vous que bash dispose de variables de tableau?
seq=1
num=4
until [[ $seq -gt $num ]];do
count[$seq]=`echo "$tab"|grep -w $seq|awk '{print $5}'`
seq=$(($seq+1))
done
echo ${count[*]}
Ou sans tableaux:
seq=1
num=4
until [[ $seq -gt $num ]];do
eval count$seq=`echo "$tab"|grep -w $seq|awk '{print $5}'`
eval echo \$count$seq
seq=$(($seq+1))
done
Oui, comme ceci (au moins en bash):
$ count1=xyz
$ seq=1
$ value=`eval echo \$\{count$seq\}`
$ echo $value
Essayez ceci:
varName=a
for i in 1 2 3
do
eval $varName$i=stuff
eval var=\$varName$i
echo $var
done
Certaines versions de shell vous permettent également d'utiliser $ {! var} pour référencer indirectement des variables