Se ho capito bene, penso che tu voglia fondamentalmente passare in rassegna le liste di valori, e poi readun'altra all'interno del ciclo.
Ecco alcune opzioni, 1 e 2 sono probabilmente le più sagge.
1. Emulare le matrici con stringhe
Avere array 2D sarebbe bello, ma non proprio possibile in Bash. Se i tuoi valori non hanno spazi bianchi, una soluzione alternativa per approssimare è attaccare ogni set di tre numeri in una stringa e dividere le stringhe all'interno del ciclo:
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
Ovviamente potresti usare anche qualche altro separatore, ad esempio for x in 1:2:3 ...e IFS=: read a b c <<< "$x".
2. Sostituire il tubo con un altro reindirizzamento per liberare lo stdin
Un'altra possibilità è quella di avere la read a b clettura da un altro fd e indirizzare l'input su quello (questo dovrebbe funzionare in una shell standard):
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
E qui puoi anche usare una sostituzione di processo se vuoi ottenere i dati da un comando: while read a b c <&3; ...done 3< <(echo $'1 2 3\n4 5 6')(la sostituzione di processo è una funzione bash / ksh / zsh)
3. Prendi invece l'input dell'utente da stderr
Oppure, viceversa, usando una pipe come nel tuo esempio, ma hai l'input dell'utente readda stderr(fd 2) anziché da stdindove proviene la pipe:
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
Leggere da stderrè un po 'strano, ma in realtà spesso funziona in una sessione interattiva. (Potresti anche aprire esplicitamente /dev/tty, supponendo che tu voglia effettivamente bypassare qualsiasi reindirizzamento, ecco cosa lessusa roba simile per ottenere l'input dell'utente anche quando i dati vengono reindirizzati ad esso.)
Sebbene l'utilizzo in stderrquesto modo potrebbe non funzionare in tutti i casi e se si utilizza un comando esterno anziché read, è necessario aggiungere almeno un gruppo di reindirizzamenti al comando.
Inoltre, vedi Perché la mia variabile è locale in un ciclo "while read", ma non in un altro loop apparentemente simile? per alcuni problemi riguardanti ... | while.
4. Affettare le parti di un array secondo necessità
Suppongo che potresti anche approssimare un array 2D ish copiando sezioni di un normale unidimensionale:
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
Puoi anche assegnare ${a[0]}ecc. A a, becc. Se vuoi nomi per le variabili, ma Zsh lo farebbe molto più bene .