Jika saya benar ini, saya pikir Anda pada dasarnya ingin mengulang daftar nilai, dan kemudian yang read
lain dalam loop.
Berikut beberapa opsi, 1 dan 2 mungkin yang paling ramah.
1. Emulasi array dengan string
Memiliki array 2D akan menyenangkan, tetapi tidak benar-benar mungkin di Bash. Jika nilai Anda tidak memiliki spasi putih, satu solusi untuk perkiraan yaitu menempel setiap set dari tiga angka ke dalam string, dan membagi string di dalam loop:
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
Tentu saja Anda bisa menggunakan pemisah lain juga, misalnya for x in 1:2:3 ...
dan IFS=: read a b c <<< "$x"
.
2. Ganti pipa dengan pengalihan lain untuk membebaskan stdin
Kemungkinan lain adalah memiliki read a b c
pembacaan dari fd lain dan mengarahkan input ke sana (ini harus bekerja dalam shell standar):
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
Dan di sini Anda juga dapat menggunakan substitusi proses jika Anda ingin mendapatkan data dari perintah: while read a b c <&3; ...done 3< <(echo $'1 2 3\n4 5 6')
(substitusi proses adalah fitur bash / ksh / zsh)
3. Ambil input pengguna dari stderr sebagai gantinya
Atau, sebaliknya, menggunakan pipa seperti pada contoh Anda, tetapi minta input pengguna read
dari stderr
(fd 2) alih-alih dari stdin
mana pipa itu berasal:
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
Membaca dari stderr
agak aneh, tetapi sebenarnya sering bekerja dalam sesi interaktif. (Anda juga dapat membuka secara eksplisit /dev/tty
, dengan asumsi Anda ingin benar-benar memintas pengalihan, itulah hal-hal seperti apa yang less
digunakan untuk mendapatkan input pengguna bahkan ketika data disalurkan ke sana.)
Meskipun menggunakan stderr
seperti itu mungkin tidak berfungsi dalam semua kasus, dan jika Anda menggunakan beberapa perintah eksternal read
, Anda setidaknya perlu menambahkan banyak pengalihan ke perintah.
Juga, lihat Mengapa variabel saya lokal dalam satu loop 'sambil membaca', tetapi tidak dalam loop lain yang tampaknya serupa? untuk beberapa masalah tentang ... | while
.
4. Iris bagian array sesuai kebutuhan
Saya kira Anda juga bisa memperkirakan array 2D-ish dengan menyalin irisan satu dimensi biasa:
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
Anda juga dapat menetapkan ${a[0]}
dll. a
, b
Dll jika Anda ingin nama untuk variabel, tetapi Zsh akan melakukannya dengan lebih baik .