各反復の開始時に複数の変数を読み取り、ループへのユーザー入力を読み取る必要があるユースケースがあります。
考えられる解決策を探る方法がわかりません。
- 割り当てには標準入力ではなく別のファイルハンドルを使用してください。
for
代わりにループを使用してください...ループ内に複数の変数を割り当てる... | while read ...
方法がわかりませんfor
echo -e "1 2 3\n4 5 6" |\ while read a b c; do echo "$a -> $b -> $c"; echo "Enter a number:"; read d ; echo "This number is $d" ; done
ベストアンサー1
read
私が正しくしている場合は、基本的に値のリストを繰り返してから、ループ内で別の値を繰り返したいと思います。
ここにはいくつかのオプションがあります。 1と2はおそらく最も賢いでしょう。
1. 文字列を使用した配列シミュレーション
2D配列を持つことは良いですが、Bashでは不可能です。値にスペースがない場合のおおよその回避策は、3つの数値の各セットを文字列に貼り付けてから、ループ内で文字列を分割することです。
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
もちろん、for x in 1:2:3 ...
などの他の区切り文字を使用することもできますIFS=: read a b c <<< "$x"
。
2. パイプを無料の標準入力にリダイレクトする別のパイプと交換します。
もう1つの可能性は、別のfdから読み込み、read a b c
そのfdに直接入力することです(標準シェルで動作する必要があります)。
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
コマンドからデータをインポートするには、ここでプロセス置換を使用することもできます。 (while read a b c <&3; ...done 3< <(echo $'1 2 3\n4 5 6')
プロセス置換はbash/ksh/zshの機能です。)
3. stderrからユーザー入力を受け取る
または、代わりに例のようなパイプを使用しますが、ユーザー入力がパイプソースの代わりに(fd 2)から出るようにread
します。stderr
stdin
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
読み取りはstderr
少し奇妙ですが、実際には対話型セッションで頻繁に機能します。 (/dev/tty
実際にリダイレクトをバイパスしたい場合は、明示的に開くこともできます。これは、less
データがパイプで接続されていてもユーザーの入力を取得するために使用されるものと似ています。)
stderr
ただし、このように使用すると、すべての場合に機能するわけではなく、代わりに外部コマンドを使用している場合は、read
少なくともそのコマンドに複数のリダイレクトを追加する必要があります。
また見てください私の変数が1つの「読み込み中」ループではローカルですが、一見似ている他のループではローカルではないのはなぜですか?いくつかの関連する質問があります... | while
。
4. 必要に応じてアレイの一部をスライスします。
通常の1D配列のスライスをコピーして2D配列を近似することもできると思います。
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
変数の名前が必要な場合は、etc${a[0]}
になどを割り当てることもできますがa
、b
Zshはもっとうまくいくでしょう。。