Si entendí esto bien, creo que básicamente quieres recorrer las listas de valores, y luego read
otra dentro del ciclo.
Aquí hay algunas opciones, 1 y 2 son probablemente las más sensatas.
1. Emular matrices con cadenas
Tener matrices 2D sería bueno, pero en realidad no es posible en Bash. Si sus valores no tienen espacios en blanco, una solución alternativa para aproximarse es pegar cada conjunto de tres números en una cadena y dividir las cadenas dentro del bucle:
for x in "1 2 3" "4 5 6"; do
read a b c <<< "$x";
read -p "Enter a number: " d
echo "$a - $b - $c - $d ";
done
Por supuesto, también podría usar algún otro separador, por ejemplo, for x in 1:2:3 ...
y IFS=: read a b c <<< "$x"
.
2. Reemplace la tubería con otra redirección para liberar stdin
Otra posibilidad es tener la read a b c
lectura de otro fd y dirigir la entrada a eso (esto debería funcionar en un shell estándar):
while read a b c <&3; do
printf "Enter a number: "
read d
echo "$a - $b - $c - $d ";
done 3<<EOF
1 2 3
4 5 6
EOF
Y aquí también puede usar una sustitución de proceso si desea obtener los datos de un comando: while read a b c <&3; ...done 3< <(echo $'1 2 3\n4 5 6')
(la sustitución de proceso es una función bash / ksh / zsh)
3. Tome la entrada del usuario de stderr en su lugar
O, al revés, usando una tubería como en su ejemplo, pero tenga la entrada read
del usuario de stderr
(fd 2) en lugar de de stdin
dónde proviene la tubería:
echo $'1 2 3\n4 5 6' |
while read a b c; do
read -u 2 -p "Enter a number: " d
echo "$a - $b - $c - $d ";
done
Leer de stderr
es un poco extraño, pero en realidad a menudo funciona en una sesión interactiva. (También podría abrir explícitamente /dev/tty
, suponiendo que realmente desea omitir cualquier redirección, eso es lo que se less
usa para obtener la entrada del usuario incluso cuando los datos se canalizan a ella).
Aunque usarlo de stderr
esa manera podría no funcionar en todos los casos, y si está usando algún comando externo en lugar de read
, al menos necesitaría agregar un montón de redirecciones al comando.
Además, vea ¿Por qué mi variable es local en un bucle 'mientras se lee', pero no en otro bucle aparentemente similar? por algunos problemas relacionados ... | while
.
4. Corte partes de una matriz según sea necesario
Supongo que también podría aproximar una matriz 2D ish copiando secciones de una unidimensional normal:
data=(1 2 3
4 5 6)
n=3
for ((i=0; i < "${#data[@]}"; i += n)); do
a=( "${data[@]:i:n}" )
read -p "Enter a number: " d
echo "${a[0]} - ${a[1]} - ${a[2]} - $d "
done
También puede asignar ${a[0]}
etc. a a
, b
etc. si desea nombres para las variables, pero Zsh lo haría mucho mejor .