कैसे आम में लाइनों को दिखाने के लिए (रिवर्स भिन्न)?


170

मेरे पास पाठ फ़ाइलों की एक श्रृंखला है, जिसके लिए मैं उन पंक्तियों के बजाय आम तौर पर लाइनों को जानना चाहता हूं जो उनके बीच भिन्न हैं। कमांड लाइन यूनिक्स या विंडोज़ ठीक है।

foo:

linux-vdso.so.1 =>  (0x00007fffccffe000)
libvlc.so.2 => /usr/lib/libvlc.so.2 (0x00007f0dc4b0b000)
libvlccore.so.0 => /usr/lib/libvlccore.so.0 (0x00007f0dc483f000)
libc.so.6 => /lib/libc.so.6 (0x00007f0dc44cd000)

बार:

libkdeui.so.5 => /usr/lib/libkdeui.so.5 (0x00007f716ae22000)
libkio.so.5 => /usr/lib/libkio.so.5 (0x00007f716a96d000)
linux-vdso.so.1 =>  (0x00007fffccffe000)

इसलिए, वांछित उपयोगिता के आउटपुट के ऊपर ये दो फाइलें दी गई हैं file1:line_number, file2:line_number == matching text (बस एक सुझाव, मुझे वास्तव में इस बात की परवाह नहीं है कि वाक्यविन्यास क्या है):

foo:1, bar:3 == linux-vdso.so.1 =>  (0x00007fffccffe000)

धन्यवाद।


@ChristopherSchultz मेरी गलती। 1 उदाहरण में पहली पंक्ति 2 उदाहरण में अंतिम पंक्ति से मेल खाती है। गलती पकड़ने के लिए धन्यवाद; बदल रहा है।
मैट विल्की जूल

1
अच्छे उत्तरों के साथ एक और समान प्रश्न: unix.stackexchange.com/questions/1079/…
मोर्टेज़े

जवाबों:


210

* निक्स पर, आप कॉम का उपयोग कर सकते हैं । प्रश्न का उत्तर है:

comm -1 -2 file1.sorted file2.sorted 
# where file1 and file2 are sorted and piped into *.sorted

यहाँ का पूरा उपयोग है comm:

comm [-1] [-2] [-3 ] file1 file2
-1 Suppress the output column of lines unique to file1.
-2 Suppress the output column of lines unique to file2.
-3 Suppress the output column of lines duplicated in file1 and file2. 

यह भी ध्यान रखें कि कॉम का उपयोग करने से पहले फाइलों को क्रमबद्ध करना महत्वपूर्ण है, जैसा कि मैन पेजों में बताया गया है।


3
comm [-1] [-2] [-3] file1 file2 -1 file1 के लिए अद्वितीय लाइनों के आउटपुट कॉलम को दबाएं। -2 फाइल 2 के लिए अद्वितीय लाइनों के आउटपुट कॉलम को दबाएं। -3 फाइल 1 और फाइल 2 में डुप्लिकेट लाइनों के आउटपुट कॉलम को दबाएं।
ओजबलास

@ojblass: इसे उत्तर में जोड़ा गया।
मैट जे

6
मुझे पता चला कि कॉम का उपयोग करने से पहले फाइलों को छांटना जरूरी है। शायद जवाब में यह जोड़ें।
मैट विल्की

11
प्रश्न का संक्षिप्त उत्तर: -1 -1 file1 file2
greggles

6
आप इसका उपयोग कर सकते हैं यदि आपकी फाइलें सॉर्ट नहीं की गई हैं: कॉम -1 -2 <(सॉर्ट फाइलनेम 1) <(सॉर्ट फाइलनेम 2)
केविन व्हीलर

56

डुप्लिकेट के रूप में सूचीबद्ध प्रश्न पर यह उत्तर मिला । मैं grep को कॉम की तुलना में अधिक व्यवस्थापक-अनुकूल पाता हूं, इसलिए यदि आप बस मिलान लाइनों का सेट चाहते हैं (उदाहरण के लिए, CSV की तुलना करने के लिए उपयोगी)

grep -F -x -f file1 file2

या सरलीकृत fgrep संस्करण

fgrep -xf file1 file2

इसके अलावा, आप file2*ग्लोब का उपयोग कर सकते हैं और केवल दो के बजाय कई फाइलों के साथ आम तौर पर लाइनों की तलाश कर सकते हैं ।

कुछ अन्य आसान विविधताओं में शामिल हैं

  • -n प्रत्येक मिलान वाली पंक्ति की पंक्ति संख्या दिखाने के लिए ध्वज
  • -c केवल उन रेखाओं की संख्या की गणना करें जो मेल खाती हैं
  • -vफ़ाइल 2 में केवल उन पंक्तियों को प्रदर्शित करने के लिए जो भिन्न (या उपयोग diff) हैं।

उपयोग करना commअधिक तेज़ है, लेकिन यह गति आपकी फ़ाइलों को पहले सॉर्ट करने की कीमत पर आती है। यह 'रिवर्स डिफरेंशियल' के रूप में बहुत उपयोगी नहीं है।


धन्यवाद राइडर, यह कई लोगों के लिए कॉम से अधिक उपयोगी हो सकता है। आपको स्रोत उत्तर से लिंक करना चाहिए (दाएं हाथ की नौसेना में क्यू से जुड़े आधा दर्जन से अधिक हैं; यह खोजने के लिए थोड़ा काम है)। यह जानना भी अच्छा होगा कि जीआरपी संयुक्त राष्ट्र या अलग तरह के इनपुट के साथ कितनी अच्छी तरह काम करता है, और संबंधित पंक्ति संख्या के मिलानों को प्रिंट कर सकता है।
मैट विल्की

1
@mattwilkie मुझे अपने आप से फिसलने के -vबाद वापस आने और ध्वज के उपयोग को स्पष्ट करने की आवश्यकता महसूस हुई । मान लें कि आपके पास दो सीएसवी फाइलें फ़ाइल 1 और फाइल 2 हैं, और उनके पास ओवरलैपिंग और गैर-ओवरलैपिंग दोनों पंक्तियाँ हैं। यदि आप सभी और केवल गैर-ओवरलैपिंग पंक्तियों को चाहते हैं, तो उपयोग करने fgrep -v file1 file2से फ़ाइल 2 में गैर-ओवरलैपिंग पंक्तियों को वापस आ जाएगा, और फ़ाइल 1 में अतिरिक्त गैर-ओवरलैपिंग पंक्तियों में से कोई भी नहीं । यह कुछ के लिए स्पष्ट हो सकता है, लेकिन जोखिम की गलत व्याख्या की तुलना में स्पष्ट करने के लिए बेहतर है। इस विशेष मामले में, फ़ाइलों को सॉर्ट करना और उपयोग commकरना अभी भी बेहतर विकल्प है।
राइडर

1
वापस आने और राइडर को स्पष्ट करने के लिए धन्यवाद। अतिरिक्त ध्यान दिया जाता है और सराहना की जाती है (पुरानी चीजों को खिसकने देने के लिए सभी t0o आसान!)। मैंने स्वीकार किए गए उत्तर को बंद कर दिया है क्योंकि कॉम स्पष्ट रूप से समुदाय की पसंद है, हालांकि व्यक्तिगत रूप से मैं अभी भी इसका उपयोग करता हूं जब छंटाई अवांछित ओवरहेड होती है।
मैट विल्की

2
उपयोग करते समय एक और जटिलता grep: पहली फाइल में कोई भी खाली लाइन दूसरी फाइल में हर लाइन से मेल खाएगी। सुनिश्चित करें कि file1कोई रिक्त रेखाएँ नहीं हैं, या ऐसा लगेगा जैसे फ़ाइलें समान हैं।
क्रिस्टोफर शुल्त्ज

grep -Fxfयह मेरे लिए है।
लक्सैक्स 12

35

पहले यहाँ पूछा गया था: यूनिक्स कमांड दो फ़ाइलों में आम लाइनों को खोजने के लिए

आप पर्ल के साथ भी प्रयास कर सकते हैं (क्रेडिट यहाँ जाता है )

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2

1
धन्यवाद। मैं दोनों उत्तर स्वीकार करना चाहूंगा, क्योंकि पर्ल वन लाइनर क्रॉस प्लेटफॉर्म है। Comm को नोड मिलता है क्योंकि यह सरल है।
मैट विल्की

1
उत्तम। विंडोज़ पर साइबरविन टर्मिनल का उपयोग करना और commआसानी से उपलब्ध नहीं होना। यह सही विकल्प था।
Qix - मोनासा

3
यह इस बात की परवाह नहीं करता है कि लाइनों को कैसे आदेश दिया जाता है। यह कॉम से ज्यादा सटीक है।
enl8enmentnow

1
एक स्पष्टीकरण यहाँ है: stackoverflow.com/questions/17552789/…
क्रिस Koknat

17

मैंने बस इस थ्रेड से कॉम कमांड सीखा है, लेकिन कुछ अतिरिक्त जोड़ना चाहता था: यदि फाइलें सॉर्ट नहीं की जाती हैं, और आप मूल फाइलों को नहीं छूना चाहते हैं, तो आप सॉर्ट कमांड के आउटपुट को पाइप कर सकते हैं। यह मूल फ़ाइलों को बरकरार रखता है। बाश में काम करता है, मैं अन्य गोले के बारे में नहीं कह सकता।

comm -1 -2 <(sort file1) <(sort file2)

इसे फाइलों के बजाय कमांड आउटपुट की तुलना करने के लिए बढ़ाया जा सकता है:

comm -1 -2 <(ls /dir1 | sort) <(ls /dir2 | sort)

9

सबसे आसान तरीका है:

awk 'NR==FNR{a[$1]++;next} a[$1] ' file1 file2

फ़ाइलों को क्रमबद्ध करने के लिए आवश्यक नहीं है।


1
यह यहां के अधिकांश उत्तरों के विपरीत है, जो आपको स्रोत टेम्पलेट्स को फिर से संगठित करने की अनुमति देता है। मेरे पास एक ही आवरण से निर्मित दो फाइलें हैं, जिनमें कुछ बिंदुओं पर अलग-अलग पाठ सम्मिलित हैं। इस उत्तर ने मुझे रैपर को ठीक करने में सक्षम बनाया।
लुकास गोंजे

1

बस जानकारी के लिए, मैंने "grep -F -x -f file1 file2" की तुलना में विंडोज के लिए एक ही उपकरण बनाया है (जैसा कि मैंने विंडोज पर इस कमांड के बराबर कुछ भी नहीं पाया है)

यहाँ यह है: http://www.nerdzcore.com/?page=commonlines

उपयोग "CommonLines inputFile1 inputFile2 outputFile" है

स्रोत कोड भी उपलब्ध है (GPL)


1

में विंडोज आप एक का उपयोग कर सकते Powershell के साथ स्क्रिप्ट CompareObject

compare-object -IncludeEqual -ExcludeDifferent -PassThru (get-content A.txt) (get-content B.txt)> MATCHING.txt | Out-Null #Find Matching Lines

CompareObject:

  • शामिल करें बिना -ExcludeDifferent के बिना: सब कुछ
  • बिना -IncueEqual के बहिष्कृत करें: कुछ भी नहीं
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.