जांचें कि क्या फ़ाइल की सभी लाइनें अलग-अलग फ़ाइल में होती हैं


15

मुझे दो फाइलें मिलीं: file1 लगभग 10 000 लाइनों के साथ और कुछ सौ लाइनों वाली file2। मैं यह जांचना चाहता हूं कि क्या file1 में file2 की सभी लाइनें मौजूद हैं। वह है: is लाइन ℓ ∈ file2: ∀। File1

क्या किसी को यह नहीं पता होना चाहिए कि इन प्रतीकों का क्या मतलब है या क्या "जाँच करें कि क्या file2 की सभी लाइनें file1 में होती हैं" का अर्थ है: या तो फाइलों में कई समकक्ष रेखाएं प्रभावित नहीं करती हैं कि क्या चेक रिटर्न देता है कि फाइलें आवश्यकता को पूरा करती हैं या नहीं।

मैं यह कैसे करु?


2
क्या उन फ़ाइलों में डुप्लिकेट लाइनें हैं? यदि file22 लाइनें शामिल हैं A, तो क्या आपको file1कम से कम 2 लाइनें शामिल करने की आवश्यकता है A?
स्टीफन चेज़लस

2
@ StéphaneChazelas सभी लाइनों (दोनों फ़ाइलों में) अद्वितीय होने की गारंटी है।
UTF-8

1
@ UTF-8 अपने प्रश्न को संपादित करने के लिए एक महत्वपूर्ण विवरण होगा।
डेविड ज़ेड

2
@DavidZ वर्तमान में नहीं है क्योंकि मौजूदा उत्तर उस गारंटी पर निर्भर नहीं हैं। तो अब प्रश्न को संपादित करके, मैं उत्तरों के स्पष्ट दायरे को कम कर दूँगा।
UTF-8 10

@ UTF-8 मैं ऐसा मानता हूं, हालांकि यह प्रश्न इसके बिना थोड़ा अस्पष्ट है, उदाहरण के लिए, यदि फ़ाइल 2 में 5 बार एक पंक्ति होती है, तो क्या उस लाइन को भी फ़ाइल 1 में 5 बार घटित होना है (जैसा कि केवल एक बार विरोध किया जाता है)? यदि आपके पास वह आवश्यकता होती है, तो ऐसा नहीं लगता है कि कोई भी मौजूदा जवाब काम करेगा, इसलिए मैं कम से कम किसी ऐसी चीज में संपादन करने का सुझाव दूंगा जिससे यह स्पष्ट हो कि इसका मतलब यह नहीं है।
डेविड जेड

जवाबों:


19
comm -13 <(sort -u file_1) <(sort -u file_2)

यह कमांड विशिष्ट लाइनों को आउटपुट करेगा file_2। इसलिए, यदि आउटपुट खाली है, तो सभी file_2लाइनें अंदर समाहित हैं file_1

कॉम के आदमी से:

   With  no  options,  produce  three-column  output.  Column one contains
   lines unique to FILE1, column two contains lines unique to  FILE2,  and
   column three contains lines common to both files.

   -1     suppress column 1 (lines unique to FILE1)

   -2     suppress column 2 (lines unique to FILE2)

   -3     suppress column 3 (lines that appear in both files)

@don_crissti सच। फिक्स्ड: -uविकल्प sortकमांड में जोड़ा गया । अब, दोनों तरह की फाइलों में केवल अनोखी लाइनें बची हैं।
मिनीमैक्स

अजीब तरह से बस समाधान! क्या यह सिंटैक्स किसी भी प्रोग्राम पर लागू होता है जो फ़ाइलों की अपेक्षा करता है? मैंने हमेशा सोचा कि <स्टड में पाइप लगाया गया था। क्या ब्रैकेट शब्द इसमें परिवर्तन करता है?
UTF-8

2
@ UTF-8 इसे प्रक्रिया प्रतिस्थापन कहा जाता है । आप इसके बारे में यहां पढ़ सकते हैं । और हां, यह एक अस्थायी फ़ाइल की तरह व्यवहार करता है, इसलिए इसका उपयोग किसी भी प्रोग्राम में वास्तविक फ़ाइलों के बजाय किया जा सकता है, जो फ़ाइलों की अपेक्षा करता है।
मिनीमैक्स

यदि यह कुछ ऐसा है जो आप अक्सर करते हैं, तो आप file_1निर्धारित रूप में संग्रहीत करना चाह सकते हैं । टाइपिंग और समय दोनों बचाता है।
स्टिग हेमर

7
@minimax "कोई भी" को छोड़कर अच्छी टिप्पणी। प्रक्रिया प्रतिस्थापन, जबकि अद्भुत, सभी मामलों में उपयोग नहीं किया जा सकता है, क्योंकि परिणामी "फाइलें" धाराएं हैं और वास्तविक फाइलें नहीं हैं। इसका मतलब है कि वे एक सामान्य फ़ाइल की तरह "खोजी" नहीं हैं, और इसका उपयोग केवल तभी किया जा सकता है जब प्रोग्राम शुरुआत से फ़ाइल को सामान्य रूप से पढ़ता है, और तब नहीं जब प्रोग्राम कुछ फ़ाइल-केवल कार्यक्षमता का उपयोग करता है जैसे कि किसी विशिष्ट बिंदु की तलाश में या शुरू से शुरू करने के लिए rewinding। खुशी से, अधिकांश कार्यक्रमों को बस उनकी फ़ाइलों को पढ़ा (), और इसलिए प्रक्रिया प्रतिस्थापन अधिकांश कार्यक्रमों के साथ काम करता है, लेकिन "कोई भी" कार्यक्रम नहीं।
Law29

7
[ $(grep -cxFf file2 <(sort -u file1)) = $(sort -u file2 | wc -l) ] && 
  echo all there || 
  echo some missing

यदि फ़ाइल 2 में फ़ाइल 2 की अद्वितीय संख्या (फ़ाइल की अद्वितीय पंक्तियों) की संख्या फ़ाइल 2 में अद्वितीय लाइनों की संख्या के समान है, तो वे सभी वहां मौजूद हैं; अन्यथा, वे नहीं हैं।


5

जीएनयू का उपयोग करना awkजहां यह विशिष्ट length(array)सुविधा का समर्थन करता है (और कुछ अन्य awkकार्यान्वयन जो समर्थन कर सकते हैं) और फाइलों को क्रमबद्ध करने की आवश्यकता नहीं है।

gawk 'FNR==NR{seen[$0];next} ($0 in seen){delete seen[$0]};
    END{print (!length(seen))?"Matched":"Not Matched"}' file2 file1

यह फाइल 2 को एक सरणी में पढ़ रहा है जिसे फाइल 2seen की पूरी लाइन की कुंजी के साथ कहा जाता है ।

फिर फ़ाइल 1 पढ़ें और प्रत्येक पंक्ति के लिए यदि सरणी में लाइनों के साथ मिलान किया गया है तो उस कुंजी को हटा दें।

अंत में यदि सरणी खाली था, तो file2 में सभी लाइनें file1 में मौजूद हैं और प्रिंट करेंगी Matched, अन्यथा प्रदर्शित होंगी Not Matched


सभी awkकार्यान्वयन में अनुकूलता के लिए ।

awk 'FNR==NR{seen[$0];next} ($0 in seen){delete seen[$0]};
    END{for(x in seen);print (!x)?"Matched":"Not Matched"}' file2 file1

केवल फ़ाइल 2 में अगर व्हाट्सएप के साथ खाली लाइनों / या लाइनों को अनदेखा करने के लिए , आपको उन्हें सरणी में पढ़ना छोड़ने के NFलिए शर्त में जोड़ना होगा NR==FNR && NF {...


length(array)gawk-only AFAIK है; यह निश्चित रूप से POSIX नहीं है।
dave_thompson_085

@ dave_thompson_085 सही है, मैंने अपना उत्तर अपडेट कर दिया है। धन्यवाद
αғsнιη

3

उपयोग करके commआप उन पंक्तियों को पा सकते हैं जो दोनों फाइलों में आम हैं।

comm -12 file1 file2

man commअधिक जानकारी के लिए एक नज़र है


सही है कि यह दोनों फाइलों में आम लाइनों को वापस कर रहा है, लेकिन यह ओपी के क्यू के लिए एक उत्तर प्रदान नहीं करता है जहां अगर आपके पास फ़ाइल 2 में एक पंक्ति थी जो फ़ाइल 1 में बाहर नहीं निकलती है, इसलिए फ़ाइल 2 में फ़ाइल 2 की सभी लाइनें मौजूद नहीं हैं।
α atsнιη

1
फ़ाइलों को सॉर्ट किया जाना चाहिए। आदमी से " comm- दो क्रमबद्ध फ़ाइलों की तुलना लाइन द्वारा लाइन करें"।
मिनीमैक्स

@MiniMax सही है। यह काम नहीं करता है। उपयोग करने वाले अन्य उत्तर commमें एक समाधान होता है जो स्पष्ट रूप से गलत नहीं है। जब मैं आपकी कमांड चलाता हूं, मुझे चेतावनी मिलती है कि फाइलें क्रमबद्ध क्रम में नहीं हैं और बहुत सारी लाइनें जो निश्चित रूप से दोनों फाइलों में हैं।
UTF-8

3
diff -q <(sort -u file2) <(grep -Fxf file2 file1 | sort -u)

कोई उत्पादन का उत्पादन होगा, तो file1शामिल सभी लाइनों में file2और स्थिति के साथ बाहर निकलें 0, अन्यथा यह की तरह कुछ प्रिंट होगा

Files /proc/self/fd/11 and /proc/self/fd/12 differ

और स्थिति से बाहर निकलें 1


2

पायथन कार्यक्रम का उपयोग करें:

#!/usr/bin/env python3
import sys

def open_arg(path):
    return sys.stdin if path == '-' else open(path)

def strip_linebreak(s):
    return s[:-1] if s.endswith('\n') else s

with open_arg(sys.argv[1]) as pattern_file:
    patterns = set(map(strip_linebreak, pattern_file))

with open_arg(sys.argv[2]) as dataset_file:
    for l in map(strip_linebreak, dataset_file):
        patterns.remove(l)
        if not patterns:
            break

sys.exit(int(bool(patterns)))

उपयोग:

python3 contains-all.py file2 file1

प्रोग्राम से बाहर निकलने की स्थिति इंगित करती है कि क्या फ़ाइल 2 के सभी पैटर्न मेल खाते थे:

  • 0 (सफलता) का मतलब है कि सभी पैटर्न का मिलान किया गया।
  • 1 (विफलता) का अर्थ है कि कुछ पैटर्न का मिलान नहीं किया गया था।

एक खोल (स्क्रिप्ट) में बाहर निकलें स्थिति क्वेरी करने के लिए आप या तो उपयोग कर सकते हैं $?विशेष चर या अन्य भाव है कि आदेश से बाहर निकलें स्थिति का मूल्यांकन, जैसे शॉर्ट सर्किट ऑपरेटरों &&और ||और की तरह सशर्त भाव ifया while। उदाहरण:

if python3 compare-all.py file2 file1 && some-other --condition; then
    # do stuff
fi

1

combineMoreutils से आपको उन सभी लाइनों को दिखाया जाएगा जिनमें से file2नहीं हैं file1:

combine file2 not file1

तब आप इसे पाइप लाइन की संख्या गिन सकते हैं wc -l, जैसे:

if [ $(combine file2 not file1 | wc -l) != 0 ]; then
  echo "lines missing"
else
  echo "You're fine"
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.