Apakah ada cara untuk menentukan beberapa variabel (bukan hanya bilangan bulat) dalam forloop bash? Saya mungkin memiliki 2 file yang mengandung teks sewenang-wenang yang harus saya kerjakan.
Apa yang saya butuhkan secara fungsional adalah sesuatu seperti ini:
for i in $(cat file1) and j in $(cat file2);do command $i $j;done
Pertama, Jangan membaca baris untuk , karena ada beberapa masalah yang tidak dapat dihindari dengan membaca baris melalui pemisahan kata.
Dengan asumsi file dengan panjang yang sama, atau jika Anda hanya ingin mengulang sampai dua file lebih pendek dibaca, solusi sederhana dimungkinkan.
while read -r x && read -r y <&3;do...done<file1 3<file2
Menyusun solusi yang lebih umum sulit karena ketika readmengembalikan salah dan beberapa alasan lainnya. Contoh ini dapat membaca jumlah aliran acak dan kembali setelah input terpendek atau terpanjang.
#!/usr/bin/env bash# Open the given files and assign the resulting FDs to arrName.# openFDs arrname file1 [file2 ...]
openFDs(){local x y i arr=$1
[[-v $arr ]]||return1
shift
for x;do{ exec {y}<"$x";}2>/dev/null ||return1
printf -v "${arr}[i++]"%d "$y"done}# closeFDs FD1 [FD2 ...]
closeFDs(){local x
for x;do
exec {x}<&-done}# Read one line from each of the given FDs and assign the output to arrName.# If the first argument is -l, returns false only when all FDs reach EOF.# readN [ -l ] arrName FD1 [FD2 ...]
readN(){if[[ $1 ==-l ]];thenlocal longest
shift
elselocal longest=filocal i x y status arr=$1
[[-v $arr ]]||return1
shift
for x;doif IFS= read -ru "$x""${arr}[i]"||{ unset -v "${arr}[i]";[[ ${longest+_}]]&&return1;};then
status=0fi((i++))donereturn ${status:-1}}# readLines file1 [file2 ...]
readLines(){local-a fds lines
trap 'closeFDs "${fds[@]}"' RETURN
openFDs fds "$@"||return1while readN -l lines "${fds[@]}";do
printf '%-1s '"${lines[@]}"
echo
done}{
readLines /dev/fd/{3..6}||{ echo 'error occured'>&2; exit 1;}}<<<$'a\nb\nc\nd'3<&0<<<$'1\n2\n3\n4\n5'4<&0<<<$'x\ny\nz'5<&0<<<$'7\n8\n9\n10\n11\n12'6<&0# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:
Jadi tergantung pada apakah readNmendapat -l, outputnya juga
a 1 x 7
b 2 y 8
c 3 z 9
d 41051112
atau
a 1 x 7
b 2 y 8
c 3 z 9
Harus membaca beberapa aliran dalam satu lingkaran tanpa menyimpan semuanya ke dalam beberapa array tidak terlalu umum. Jika Anda hanya ingin membaca array Anda harus melihatnya mapfile.
||tidak bekerja untuk saya. Ini memproses file1 kemudian file2 , tetapi itu tetap membuat file disinkronkan dengan &&, yang keluar dari loop sementara setelah bukti pertama . - GNU bash 4.1.5
Peter.O
Saya tidak punya waktu luang untuk menguji - ya Anda mungkin ingin kedua elemen per iterasi. Operator ||"daftar" mengalami hubungan arus pendek seperti di sebagian besar bahasa. Tentunya ini telah dijawab ribuan kali sebelumnya ...
ormaaj
Intinya bukan frekuensi seberapa sering sesuatu telah disebutkan sebelumnya. Sebaliknya, kode yang saat ini Anda tunjukkan dalam jawaban Anda tidak berfungsi . Berdasarkan "Anda mungkin menginginkan kedua elemen ..", sepertinya Anda masih belum mengujinya.
Peter.O
@ Peter. O Saya sadar. Sudah diperbaiki.
ormaaj
2
Dilakukan; selesai - Anda perlu dua fors dan dua done:
for i in $(< file1);dofor j in $(< file2);do echo $i $j;done;done
File2, tentu saja, diproses untuk setiap kata dalam file1 satu kali.
Menggunakan <bukannya cat harusnya merupakan peningkatan kinerja yang biasa-biasa saja dalam banyak kasus. Tidak ada subproses yang terlibat. (Tidak yakin tentang kalimat terakhir).
Terkompresi:
for i in $(< file1)dofor j in $(< file2)do
echo $i $j
donedone
Jika Anda tidak suka membaca kata-kata, tetapi garis, dan pertahankan spasi putih, gunakan sementara dan baca:
while read line;dowhile read second;do echo "${line}${second}";done<file2 ;done<file1
Jika Anda ingin menambahkan 2 file, dan tidak membuat sarang:
Anda mengatakan tidak ada subproses yang terlibat. Bukankah () sebuah subkulit? Saya tidak ingin menjadi raksasa tetapi saya tidak yakin apa yang terjadi sekarang. Sebagai contoh, saya tahu bahwa ketika saya memiliki skrip dan saya tidak ingin itu mencemari shell saat ini dengan cd misalnya, saya melakukannya di dalam (). Juga berjalan (tidur 4) & misalnya diikuti oleh ps menunjukkan proses masih berjalan. Tolong jelaskan.
Silverrocker
Yah - maaf, saya sangat banyak bertindak tanpa dasar di sini. Saya pikir saya mendengarnya, tapi mungkin itu hanya <dibandingkan dengan cat. Dan saya tidak yakin bagaimana cara mengujinya, dan kapan itu akan menjadi sangat penting. Jika pipa dipanggil, variabel dalam subproses tidak muncul hingga proses utama, tetapi kami tidak memiliki variabel di sini. Saya menyerang melalui kalimat kritis, sampai seseorang dapat mengklarifikasi hal itu.
pengguna tidak diketahui
0
whilememiliki sintaksis interesitng. Anda dapat menempatkan beberapa perintah sebelum do ... whileloop, dan case yang dimaksud mungkin perlu menyulap fitur ini, tergantung pada persyaratan khusus Anda: apakah Anda membaca hingga akhir file terpanjang, atau hanya ke ujung yang terpendek.
Sebagai contoh, read || readhanya tidak bekerja (sesuai kebutuhan pertanyaan ini), becase ketika membaca dari file pertama adalah true, file kedua ini dibaca adalah dilewati sampai file pertama sudah dibaca dari awal sampai akhir ... Kemudian, karena status masih true, loop sementara berlanjut dan membaca file kedua dari awal hingga selesai.
read && readakan membaca file secara bersamaan (sinkron) jika Anda hanya ingin membaca sejauh file terpendek. Namun, jika Anda ingin membaca kedua file eof, maka Anda harus bekerja dengan while'spersyaratan sintaks, yaitu. dengan perintah segera sebelum para do whilelingkaran menghasilkan kode kembali non-nol untuk keluar dari sementara loop.
Berikut adalah contoh cara membaca kedua file ke eof
||
tidak bekerja untuk saya. Ini memproses file1 kemudian file2 , tetapi itu tetap membuat file disinkronkan dengan&&
, yang keluar dari loop sementara setelah bukti pertama . - GNU bash 4.1.5||
"daftar" mengalami hubungan arus pendek seperti di sebagian besar bahasa. Tentunya ini telah dijawab ribuan kali sebelumnya ...Dilakukan; selesai - Anda perlu dua fors dan dua done:
File2, tentu saja, diproses untuk setiap kata dalam file1 satu kali.
Menggunakan <bukannya cat harusnya merupakan peningkatan kinerja yang biasa-biasa saja dalam banyak kasus.
Tidak ada subproses yang terlibat.(Tidak yakin tentang kalimat terakhir).Terkompresi:
Jika Anda tidak suka membaca kata-kata, tetapi garis, dan pertahankan spasi putih, gunakan sementara dan baca:
Jika Anda ingin menambahkan 2 file, dan tidak membuat sarang:
Jika Anda ingin men-zip 2 file, gunakan tempel:
sumber
<
dibandingkan dengancat
. Dan saya tidak yakin bagaimana cara mengujinya, dan kapan itu akan menjadi sangat penting. Jika pipa dipanggil, variabel dalam subproses tidak muncul hingga proses utama, tetapi kami tidak memiliki variabel di sini. Saya menyerang melalui kalimat kritis, sampai seseorang dapat mengklarifikasi hal itu.while
memiliki sintaksis interesitng. Anda dapat menempatkan beberapa perintah sebelumdo ... while
loop, dan case yang dimaksud mungkin perlu menyulap fitur ini, tergantung pada persyaratan khusus Anda: apakah Anda membaca hingga akhir file terpanjang, atau hanya ke ujung yang terpendek.Sebagai contoh,
read || read
hanya tidak bekerja (sesuai kebutuhan pertanyaan ini), becase ketika membaca dari file pertama adalahtrue
, file kedua ini dibaca adalah dilewati sampai file pertama sudah dibaca dari awal sampai akhir ... Kemudian, karena status masihtrue
, loop sementara berlanjut dan membaca file kedua dari awal hingga selesai.read && read
akan membaca file secara bersamaan (sinkron) jika Anda hanya ingin membaca sejauh file terpendek. Namun, jika Anda ingin membaca kedua fileeof
, maka Anda harus bekerja denganwhile's
persyaratan sintaks, yaitu. dengan perintah segera sebelum parado while
lingkaran menghasilkan kode kembali non-nol untuk keluar dari sementara loop.Berikut adalah contoh cara membaca kedua file ke eof
(Anda mungkin ingin menguji eof3 dan eof4 sebelum membaca, tetapi gagasan umum ada di sana, terutama dalam kondisi benar / salah akhir.
sumber