विधि 1: जो आप जानते हैं उसका उपयोग करें
चूँकि आप पहले से ही जानते हैं कि किसी एक फाइल को कैसे लूप किया जाता है, आप फाइलों को मिला सकते हैं और फिर संयुक्त फाइलों को प्रोसेस कर सकते हैं। कमांड paste
दो फाइल लाइन लाइन से जुड़ती है। यह दो फ़ाइलों से आने वाली लाइनों के बीच एक टैब लगाता है, इसलिए यह समाधान मानता है कि आपकी फ़ाइल नामों में कोई टैब नहीं हैं। (आप विभाजक को बदल सकते हैं लेकिन आपको एक वर्ण ढूंढना होगा जो फ़ाइल नाम में मौजूद नहीं है।)
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
यदि आप रिक्त लाइनों को छोड़ना चाहते हैं, तो आपको इसे प्रत्येक फ़ाइल में अलग से करने की आवश्यकता है, क्योंकि paste
हो सकता है कि एक फ़ाइल से कोई रिक्त रेखा किसी अन्य फ़ाइल से गैर-रिक्त रेखा से मेल खाए। आप grep
गैर-रिक्त लाइनों को फ़िल्टर करने के लिए उपयोग कर सकते हैं ।
paste -- <(grep '[^[:space:]]' "$list1.txt") <(grep '[^[:space:]]' "list2.txt") |
while IFS=$'\t' read -r file1 file2 rest; do
…
ध्यान दें कि यदि दो फ़ाइलों की लंबाई अलग-अलग है, तो आपको एक खाली मिलेगा $file2
(चाहे जो सूची पहले समाप्त हो गई हो)।
विधि 2: दो फ़ाइलों पर लूप
जब आप लूप की स्थिति में चाहते हैं, तो आप एक जटिल के रूप में एक कमांड डाल सकते हैं। यदि आप डालते हैं read file1 <&3 && read file2 <&4
तो लूप तब तक चलेगा जब तक दोनों फाइलों को पढ़ने के लिए एक पंक्ति होती है, यानी जब तक कि एक फ़ाइल नहीं निकल जाती है।
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
यदि आप रिक्त लाइनों को छोड़ना चाहते हैं, तो यह थोड़ा अधिक जटिल है, क्योंकि आपको दो फाइलों में स्वतंत्र रूप से स्किपिंग करनी है। आसान तरीका यह है कि समस्या को दो भागों में तोड़ दिया जाए: एक फ़ाइल से रिक्त लाइनों को छोड़ दें, और गैर-रिक्त लाइनों को संसाधित करें। रिक्त लाइनों को छोड़ने के लिए एक विधि grep
ऊपर के माध्यम से प्रक्रिया करना है। <
पुनर्निर्देशन ऑपरेटर के बीच आवश्यक स्थान के लिए बाहर देखो और <(
कि एक आदेश susbtocation शुरू होता है।
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3< <(grep '[^[:space:]]' "$list1.txt") 4< <(grep '[^[:space:]]' "list2.txt")
एक और तरीका एक फ़ंक्शन लिखना है जो व्यवहार करता है read
लेकिन खाली लाइनों को छोड़ देता है। यह फ़ंक्शन read
लूप में कॉल करके काम कर सकता है । यह एक फ़ंक्शन नहीं है, लेकिन एक फ़ंक्शन सबसे अच्छा तरीका है, दोनों को आपके कोड को व्यवस्थित करना है और क्योंकि उस कोड को दो बार कॉल करने की आवश्यकता है। फ़ंक्शन में, ${!#}
बैश निर्माण का एक उदाहरण है ${!VARIABLE}
जो चर के मूल्य का मूल्यांकन करता है जिसका नाम मूल्य है VARIABLE
; यहाँ वैरिएबल वह विशेष वैरिएबल है #
जिसमें स्थितीय पैरामीटर की संख्या समाहित है, इसलिए ${!#}
अंतिम स्थितीय पैरामीटर है।
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
।