Se ho capito bene, penso che tu voglia fondamentalmente passare in rassegna le liste di valori, e poi read
un'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 c
lettura 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 read
da stderr
(fd 2) anziché da stdin
dove 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 less
usa roba simile per ottenere l'input dell'utente anche quando i dati vengono reindirizzati ad esso.)
Sebbene l'utilizzo in stderr
questo 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
, b
ecc. Se vuoi nomi per le variabili, ma Zsh lo farebbe molto più bene .