यूनिक्स में लाइन द्वारा दो अलग-अलग फ़ाइलों की लाइन की तुलना कैसे करें?


13

file1:

123
234
345
456

करें 2:

123
234
343
758

अपेक्षित आउटपुट: File3:

TRUE
TRUE
FALSE
FALSE

इसलिए कोड को दो फ़ाइलों की तुलना करनी चाहिए और यदि वह मेल खाता है तो 'TRUE' को प्रिंट करें अन्यथा उसे नई फ़ाइल में 'FALSE' प्रिंट करना चाहिए। किसी को भी इस के लिए समाधान प्रदान कर सकते हैं?


10
यदि दो फाइलें असमान लंबाई की हैं तो क्या होगा? इस समस्या के समाधान के किस हिस्से से आपको समस्या हो रही है?
Kusalananda

9
आप पर एक नज़र रखना चाहते हो सकता है diff
पनकी

2
इन स्थितियों में अन्य उपयोगी कमांड है comm। यह उन पंक्तियों को सूचीबद्ध करना आसान बनाता है जिनमें दोनों फाइलें आम हैं या एक या दूसरे के लिए अद्वितीय हैं।
गियाकोमो अल्जेटा

1
@GiacomoAlzetta के साथ बात commयह है कि इसके लिए हल इनपुट की आवश्यकता होती है। इसके अलावा तथ्य यह है कि प्रश्न में उदाहरण से करता क्रमबद्ध इनपुट है, सवाल कभी नहीं दावा है कि यह वास्तविक डेटा है कि इस्तेमाल किया जा रहा है और डेटा के आदेश देने के बारे में कुछ भी कहते हैं कभी नहीं।
Kusalananda

2
फ़ाइलों पर सॉर्ट-नेस लगाने के लिए α sнιη की nlट्रिक उपयोगी है comm
ग्लेन जैकमैन

जवाबों:


56

उपयोग diffके बाद, के रूप में आदेश bashया किसी अन्य खोल कि समर्थन करता है <(...) प्रतिस्थापन की प्रक्रिया या आप इसे का अनुकरण कर सकते हैं जैसा कि यहाँ दिखाया :

diff --new-line-format='FALSE'$'\n' \
     --old-line-format='' \
     --unchanged-line-format='TRUE'$'\n' \
<(nl file1) <(nl file2)

आउटपुट होगा:

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\n, प्रिंट करें FALSEयदि लाइनें अलग थीं और --old-line-format=''हम आउटपुट को अक्षम करते हैं यदि लाइन फाइल 1 के लिए अलग थी जिसे कमांड को अलग करने के लिए पुरानी फाइल के रूप में जाना जाता है (हम इन्हें स्वैप भी कर सकते हैं, जिसका अर्थ है कि उनमें से एक को FALSEदूसरे को प्रिंट करना चाहिए।)

--unchanged-line-format='TRUE'$'\n', प्रिंट TRUEयदि रेखाएँ समान थीं। $'\n'सी-शैली से बचने वाक्य रचना प्रत्येक पंक्ति उत्पादन के बाद एक नई लाइन मुद्रण के लिए प्रयोग किया जाता है।


24

मान लें कि फ़ाइलों में कोई टैब-वर्ण नहीं हैं:

$ paste file1 file2 | awk -F '\t' '{ print ($1 == $2 ? "TRUE" : "FALSE") }'
TRUE
TRUE
FALSE
FALSE

यह pasteदो टैब-सीमांकित कॉलम बनाने के लिए उपयोग करता है, जिसमें दोनों फ़ाइलों की सामग्री दोनों कॉलम में होती है। awkआदेश प्रत्येक पंक्ति पर दो कॉलम तुलना करता है और प्रिंट TRUEकरता है, तो कॉलम ही और नहीं तो प्रिंट कर रहे हैं FALSE


10

मान लें कि दोनों फ़ाइलों में समान पंक्तियाँ हैं:

awk '{getline f2 < "file2"; print f2 == $0 ? "TRUE" : "FALSE"}' file1

यह एक संख्यात्मक तुलना कर रहा है अगर तुलना करने के लिए तार संख्या और शाब्दिक अन्यथा हैं। उदाहरण के लिए, 100और 1.0e2समान माना जाएगा। f2"" == $0किसी भी मामले में एक शाब्दिक तुलना के लिए मजबूर करने के लिए बदलें ।

awkकार्यान्वयन के आधार पर , शाब्दिक तुलना इस तरह की जाएगी memcmp()(जैसे बाइट-टू-बाइट तुलना) का उपयोग करके या जैसे strcoll()कि (चाहे दो तार लोकेल के टकराव क्रम में समान हो)। यह कुछ स्थानों में फर्क कर सकता है जहां कुछ वर्णों के लिए क्रम ठीक से परिभाषित नहीं है, आपके नमूने में सभी दशमलव अंक इनपुट पर नहीं।


7

अजगर ३

with open('file1') as file1, open('file2') as file2:
    for line1, line2 in zip(file1, file2):
        print(line1 == line2)

आउटपुट:

True
True
False
False

यदि आपको जरूरत है TRUEऔर FALSEअपरकेस में, प्रिंट लाइन को इनमें से किसी एक के साथ बदलें:

print(str(line1 == line2).upper())
print('TRUE' if line1 == line2 else 'FALSE')

2
पायथन 2 में, import itertoolsपहले एक करें , और फिर itertools.izipइसके बजाय का उपयोग करें zip। अन्यथा यह मेमोरी में दोनों फाइलों को पढ़ेगा, संभवतः बहुत अधिक मेमोरी का उपयोग करके।
pts

4

में bash, एक में प्रत्येक फ़ाइल से पढ़ने while, पाश पढ़ने लाइनों की तुलना और मुद्रण TRUEया FALSEउचित रूप से:

while IFS= read -r -u3 line1; IFS= read -r -u4 line2; do
    [[ $line1 == $line2 ]] && echo TRUE || echo FALSE
done 3<file1 4<file2

दो कॉल readक्रमशः फाइल डिस्क्रिप्टर 3 और 4 से पढ़ते हैं। फ़ाइलों को लूप में दो इनपुट पुनर्निर्देशन के साथ इन पर पुनर्निर्देशित किया जाता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.