¿Cómo puedo acceder a las variables que se nombran secuencialmente por un bucle mientras todavía están dentro del bucle?
Pregunta
Estoy tratando de entender si es posible crear un conjunto de variables que estén numeradas en función de otra variable (usando eval) en un ciclo, y luego invocarlo antes de que finalice el ciclo.
Como ejemplo, he escrito una secuencia de comandos llamada pregunta (El primer comando es mostrar cuál es el contenido 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
Cuando ejecuto esto obtengo
(23:32:23\[deco@S.Man)
[~/bin]$ ./question
1195
1471
1538
1409
Que es exactamente lo que esperaría, pero hay una manera de mover los comandos de eco dentro del bucle hasta que parte del bucle está haciendo eco del valor de la variable que se acaba de crear. Algo así como:
until [[ $seq -gt $num ]];do
eval count$seq=`echo "$tab"|grep -w $seq|awk '{print $5}'`
seq=$(($seq+1))
echo "$count$seq"
done
PD: Perdón si mi formato está desactivado ... la primera vez que publico aquí, y solo sé el descuento de reddit.
Solución
Usar indirección:
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
No hay necesidad de otra evaluación.
Otros consejos
No responde exactamente su pregunta, pero ... ¿sabía que bash tiene variables de matriz?
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[*]}
O sin matrices:
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
Sí, así (al menos en bash):
$ count1=xyz
$ seq=1
$ value=`eval echo \$\{count$seq\}`
$ echo $value
Prueba esto:
varName=a
for i in 1 2 3
do
eval $varName$i=stuff
eval var=\$varName$i
echo $var
done
algunas versiones de shell también le permiten usar $ {! var} para hacer referencia indirecta a variables