Wenn ich das richtig verstanden habe, denke ich, dass Sie im Grunde genommen eine Liste von Werten und dann eine read
andere innerhalb der Schleife durchlaufen möchten .
Hier sind einige Optionen, 1 und 2 sind wahrscheinlich die vernünftigsten.
1. Emulieren Sie Arrays mit Strings
2D-Arrays zu haben wäre schön, aber in Bash nicht wirklich möglich. Wenn Ihre Werte kein Leerzeichen haben, besteht eine Problemumgehung darin, jeden Satz von drei Zahlen in eine Zeichenfolge zu kleben und die Zeichenfolgen innerhalb der Schleife aufzuteilen:
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
Natürlich können Sie auch ein anderes Trennzeichen verwenden, z . B. for x in 1:2:3 ...
und IFS=: read a b c <<< "$x"
.
2. Ersetzen Sie das Rohr durch eine andere Umleitung, um stdin freizugeben
Eine andere Möglichkeit besteht darin, das read a b c
Lesen von einem anderen fd zu haben und die Eingabe darauf zu lenken (dies sollte in einer Standard-Shell funktionieren):
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
Und hier können Sie auch eine Prozessersetzung verwenden, wenn Sie die Daten von einem Befehl abrufen möchten: while read a b c <&3; ...done 3< <(echo $'1 2 3\n4 5 6')
(Die Prozessersetzung ist eine bash / ksh / zsh-Funktion.)
3. Nehmen Sie stattdessen Benutzereingaben von stderr entgegen
Oder umgekehrt, indem Sie eine Pipe wie in Ihrem Beispiel verwenden, aber den Benutzer read
von stderr
(fd 2) eingeben lassen, anstatt stdin
woher die Pipe stammt:
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
Das Lesen von stderr
ist etwas seltsam, funktioniert aber häufig in einer interaktiven Sitzung. (Sie können auch explizit öffnen /dev/tty
, vorausgesetzt, Sie möchten Umleitungen tatsächlich umgehen. Dies wird less
verwendet, um die Benutzereingaben auch dann abzurufen, wenn die Daten an sie weitergeleitet werden.)
Obwohl die Verwendung stderr
dieser Funktion möglicherweise nicht in allen Fällen funktioniert und Sie stattdessen einen externen Befehl verwenden read
, müssen Sie dem Befehl zumindest eine Reihe von Umleitungen hinzufügen.
Siehe auch Warum befindet sich meine Variable lokal in einer 'while read'-Schleife, aber nicht in einer anderen scheinbar ähnlichen Schleife? für einige Fragen in Bezug auf ... | while
.
4. Schneiden Sie Teile eines Arrays nach Bedarf in Scheiben
Ich nehme an, Sie könnten ein 2D-ish-Array auch approximieren, indem Sie Slices eines regulären eindimensionalen Arrays kopieren:
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
Sie können auch ${a[0]}
usw. usw. zuweisen a
, b
wenn Sie Namen für die Variablen möchten, aber Zsh würde das viel besser tun .