Saya ingin tahu apakah ada cara membaca dari dua file input dalam sebuah nested loop satu baris sekaligus. Sebagai contoh, katakanlah saya punya dua file FileA
dan FileB
.
FileA:
[jaypal:~/Temp] cat filea
this is File A line1
this is File A line2
this is File A line3
FileB:
[jaypal:~/Temp] cat fileb
this is File B line1
this is File B line2
this is File B line3
Skrip Contoh Saat Ini:
[jaypal:~/Temp] cat read.sh
#!/bin/bash
while read lineA
do echo $lineA
while read lineB
do echo $lineB
done < fileb
done < filea
Eksekusi:
[jaypal:~/Temp] ./read.sh
this is File A line1
this is File B line1
this is File B line2
this is File B line3
this is File A line2
this is File B line1
this is File B line2
this is File B line3
this is File A line3
this is File B line1
this is File B line2
this is File B line3
Masalah dan output yang diinginkan:
Ini loop atas FileB sepenuhnya untuk setiap baris di FileA. Saya mencoba menggunakan continue, break, exit tetapi tidak satupun dari mereka yang dimaksudkan untuk mencapai output yang saya cari. Saya ingin skrip untuk membaca hanya satu baris dari File A dan kemudian satu baris dari FileB dan keluar dari loop dan lanjutkan dengan baris kedua dari File A dan baris kedua dari File B. Sesuatu yang mirip dengan skrip berikut -
[jaypal:~/Temp] cat read1.sh
#!/bin/bash
count=1
while read lineA
do echo $lineA
lineB=`sed -n "$count"p fileb`
echo $lineB
count=`expr $count + 1`
done < filea
[jaypal:~/Temp] ./read1.sh
this is File A line1
this is File B line1
this is File A line2
this is File B line2
this is File A line3
this is File B line3
Apakah ini mungkin dicapai dengan while?
bash
shell-script
io-redirection
jaypal singh
sumber
sumber
paste -d '\n' file1 file2
Jawaban:
Jika Anda tahu pasti bahwa beberapa karakter tidak akan pernah muncul di file pertama maka Anda dapat menggunakan tempel.
Contoh tempel menggunakan tab pembatas default:
Contoh tempel menggunakan
@
:Perhatikan bahwa itu sudah cukup jika karakter dijamin tidak terjadi pada file pertama. Ini karena
read
akan diabaikanIFS
ketika mengisi variabel terakhir. Jadi bahkan jika@
terjadi pada file kedua itu tidak akan terpecah.Contoh tempel menggunakan beberapa fitur bash untuk kode yang lebih bersih:
Fitur Bash yang digunakan: ansi c string (
$'\t'
) dan proses substitusi (<(...)
) untuk menghindari loop sementara dalam masalah subkulit .Jika Anda tidak dapat memastikan bahwa karakter apa pun tidak akan pernah muncul di kedua file, maka Anda dapat menggunakan deskriptor file .
Tidak banyak diuji. Mungkin istirahat di garis kosong.
File deskriptor nomor 0, 1, dan 2 sudah digunakan untuk stdin, stdout, dan stderr. Deskriptor file dari 3 ke atas (biasanya) gratis. Manual bash memperingatkan dari menggunakan deskriptor file yang lebih besar dari 9, karena mereka "digunakan secara internal".
Perhatikan bahwa deskriptor file terbuka diwarisi untuk fungsi shell dan program eksternal. Fungsi dan program yang mewarisi deskriptor file terbuka dapat membaca dari (dan menulis ke) deskriptor file. Anda harus berhati-hati untuk menutup semua deskriptor file yang tidak diperlukan sebelum memanggil suatu fungsi atau program eksternal.
Berikut adalah program yang sama seperti di atas dengan pekerjaan aktual (pencetakan) dipisahkan dari meta-work (membaca baris demi baris dari dua file secara paralel).
Sekarang kita berpura-pura bahwa kita tidak memiliki kendali atas kode kerja dan kode itu, untuk alasan apa pun, mencoba membaca dari deskriptor file 3.
Ini adalah contoh output. Perhatikan bahwa baris kedua dari file pertama "dicuri" dari loop.
Di sini adalah bagaimana Anda harus menutup deskriptor file sebelum memanggil kode eksternal (atau kode apa pun dalam hal ini).
sumber
Buka dua file pada deskriptor file yang berbeda . Alihkan input dari
read
built-in ke deskriptor bahwa file yang Anda inginkan terhubung. Di bash / ksh / zsh, Anda bisa menulisread -u 3
alih-alihread <&3
.Cuplikan ini berhenti ketika file terpendek telah diproses. Lihat Membaca dua file menjadi IFS sementara loop - Apakah ada cara untuk mendapatkan hasil nol diff dalam kasus ini? jika Anda ingin terus memproses hingga akhir kedua file.
Lihat juga Kapan Anda akan menggunakan deskriptor file tambahan? untuk informasi tambahan tentang deskriptor file, dan Mengapa `sementara IFS = read` sering digunakan, alih-alih` IFS =; saat membaca..`? untuk penjelasan
IFS= read -r
.sumber
Saya tahu Anda ingin skrip shell, tetapi Anda mungkin ingin melihat
paste
perintahnya.sumber
paste
juga keren.Coba perintah di bawah ini:
sumber
Atau, saya kira Anda bisa menyeruput file ke dalam variabel array yang mengikat setiap baris file ke dalam array [line_of_file_index] menggunakan perintah mapfile bash. Namun, saya tidak yakin apakah itu hanya untuk Bash3 lebih tinggi atau Bash4.
http://wiki.bash-hackers.org/commands/builtin/mapfile
sumber