Yöntem 1: Bildiklerinizi Kullanın
Bir dosya üzerinde nasıl döngü yapılacağını zaten bildiğiniz için, dosyaları birleştirebilir ve daha sonra birleştirilmiş dosyaları işleyebilirsiniz. Komut paste
iki dosyayı satır satır birleştirir. İki dosyadan gelen satırlar arasına bir sekme koyar, bu nedenle bu çözüm dosya adlarınızda hiç sekme olmadığını varsayar. (Ayırıcıyı değiştirebilirsiniz, ancak dosya adında olmayan bir karakter bulmanız gerekir.)
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
Boş satırları atlamak istiyorsanız, her dosyada ayrı ayrı yapmanız gerekir, çünkü paste
bir dosyadaki boş bir satırı başka bir dosyadaki boş olmayan bir satırla eşleştirebilir. grep
Boş olmayan satırları filtrelemek için kullanabilirsiniz .
paste -- <(grep '[^[:space:]]' "$list1.txt") <(grep '[^[:space:]]' "list2.txt") |
while IFS=$'\t' read -r file1 file2 rest; do
…
İki dosya farklı uzunluklara sahipse boş bir alan elde edeceğinizi unutmayın $file2
(ilk önce hangi listenin sona erdiğine bakılmaksızın).
Yöntem 2: İki dosya üzerinde döngü
While döngüsü durumunda istediğiniz kadar karmaşık bir komut koyabilirsiniz. Eğer koyarsanız read file1 <&3 && read file2 <&4
, döngü her iki dosya da okunacak bir çizgiye sahip olduğu sürece, yani bir dosya bitene kadar çalışır.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
Boş satırları atlamak istiyorsanız, biraz daha karmaşıktır, çünkü iki dosyada atlamayı bağımsız olarak yapmanız gerekir. Kolay yol, sorunu iki bölüme ayırmaktır: boş satırları bir dosyadan atlamak ve boş olmayan satırları işlemek. Boş satırları atlamanın bir yolu grep
yukarıdaki gibi işlem yapmaktır. Yeniden <
yönlendirme operatörü ile <(
komut susbtitüsyonu başlatan arasında gerekli boşluğa dikkat edin .
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3< <(grep '[^[:space:]]' "$list1.txt") 4< <(grep '[^[:space:]]' "list2.txt")
Başka bir yöntem de, read
boş çizgiler atlayan ancak atlayan bir işlev yazmaktır . Bu işlev read
bir döngü içinde çağrılarak çalışabilir . Bir işlev olmak zorunda değildir, ancak bir işlev hem kodunuzu düzenlemek için hem de bu kod parçasının iki kez çağrılması gerektiğinden en iyi yaklaşımdır. Fonksiyon olarak, ${!#}
darbe yapısının bir örneğidir ${!VARIABLE}
adı değişkenin değer öncelik değeri VARIABLE
; burada değişken, #
konumsal parametre sayısını içeren özel bir değişkendir , yani ${!#}
son konumsal parametre de budur.
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
.