Metode 1: gunakan apa yang Anda ketahui
Karena Anda sudah tahu cara melompati satu file, Anda dapat menggabungkan file dan kemudian memproses file gabungan. Perintah tersebut pastemenggabungkan dua file baris demi baris. Ini menempatkan tab di antara garis yang berasal dari dua file, jadi solusi ini mengasumsikan bahwa tidak ada tab di nama file Anda. (Anda dapat mengubah pemisah tetapi Anda harus menemukan karakter yang tidak ada dalam nama file.)
paste -- "$list1.txt" "list2.txt" |
while IFS=$'\t' read -r file1 file2 rest; do
diff -q -- "$file1" "$file2"
case $? in
0) status='same';;
1) status='different';;
*) status='ERROR';;
esac
echo "$status $file1 $file2"
done
Jika Anda ingin melewati baris kosong, Anda harus melakukannya di setiap file secara terpisah, karena pastemungkin cocok dengan baris kosong dari satu file dengan baris non-kosong dari file lain. Anda dapat menggunakan grepuntuk menyaring garis yang tidak kosong.
paste -- <(grep '[^[:space:]]' "$list1.txt") <(grep '[^[:space:]]' "list2.txt") |
while IFS=$'\t' read -r file1 file2 rest; do
…
Perhatikan bahwa jika kedua file memiliki panjang yang berbeda, Anda akan mendapatkan yang kosong $file2(terlepas dari daftar mana yang berakhir lebih dulu).
Metode 2: loop dua file
Anda dapat menempatkan perintah yang kompleks seperti yang Anda inginkan dalam kondisi loop sementara. Jika Anda meletakkan read file1 <&3 && read file2 <&4maka loop akan berjalan selama kedua file memiliki satu baris untuk dibaca, yaitu sampai satu file habis.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
Jika Anda ingin melompati garis kosong, ini sedikit lebih rumit, karena Anda harus melompati dua file secara mandiri. Cara mudah adalah memecah masalah menjadi dua bagian: lewati baris kosong dari satu file, dan proses baris yang tidak kosong. Salah satu metode untuk melewati garis kosong adalah dengan memproses grepseperti di atas. Waspadai ruang yang diperlukan antara <operator pengalihan dan <(yang memulai susbtitusi perintah.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3< <(grep '[^[:space:]]' "$list1.txt") 4< <(grep '[^[:space:]]' "list2.txt")
Metode lain adalah menulis fungsi yang berperilaku seperti readtetapi melompati garis kosong. Fungsi ini dapat bekerja dengan memanggil readsatu lingkaran. Itu tidak harus menjadi fungsi, tetapi fungsi adalah pendekatan terbaik, baik untuk mengatur kode Anda dan karena potongan kode itu perlu dipanggil dua kali. Dalam fungsinya, ${!#}adalah turunan dari bash construct ${!VARIABLE}yang mengevaluasi nilai dari variabel yang namanya adalah nilai VARIABLE; di sini variabelnya adalah variabel khusus #yang berisi jumlah parameter posisi, demikian ${!#}juga parameter posisi terakhir.
function read_nonblank {
while read "$@" &&
[[ ${!#} !~ [^[:space:]] ]]
do :; done
}
while read_nonblank -u 3 -r file1 && read_nonblank -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
diff.