मैं केवल जोड़ी गई और हटाई गई लाइनों को दिखाने के लिए अलग कैसे हो सकता हूं? यदि भिन्न यह नहीं कर सकता है, तो कौन सा उपकरण कर सकता है?


69

मैं केवल जोड़ी गई और हटाई गई लाइनों को दिखाने के लिए अलग कैसे हो सकता हूं? यदि भिन्न यह नहीं कर सकता है, तो कौन सा उपकरण कर सकता है?


2
आपको बेहतर ढंग से परिभाषित करने की आवश्यकता है कि आपके द्वारा जोड़े गए और हटाए गए से क्या मतलब है। विशेष रूप से, क्या कोई रेखा बदल सकती है? यदि हां, तो आप कैसे एक बदली हुई रेखा को संभालना चाहते हैं? यदि आप कड़ाई से लाइन ओरिएंटेड चेकिंग कर रहे हैं, तो एक लाइन बदलना पुरानी लाइन को हटाने और नई लाइन को जोड़े जाने के समान है। उदाहरण के लिए, दो में विभाजित होने वाली रेखा को कैसे संभालना चाहिए? जैसे दो 1 लाइन बदली? 2 लाइनें बदल गईं? 1 लाइन हटाई गई और 2 लाइनें जोड़ी गईं? जब तक आप गारंटी नहीं दे सकते कि लाइनें कभी नहीं बदलेंगी, बस जोड़ा और हटा दिया जाएगा, मुझे लगता है कि यह बेहतर परिभाषाओं के बिना विफल होने के लिए बर्बाद है।
क्रिस्टोफर कैशेल

मुझे सवाल काफी अस्पष्ट लगता है। लेकिन प्रश्न की कम से कम एक व्याख्या के साथ उत्तर दिया जा सकता हैdiff A B | grep '^[<>]'
कास्परड सिप

आप ढूंढ रहे होंगे comm
जेनी डी

@ChristopherCashell, उनका अर्थ है कि क्रम की उपेक्षा; आमतौर पर एक आम समस्या है। आमतौर पर यह एक विशिष्ट अंतर करने से पहले प्रत्येक तरफ के खंडों (लाइनों) को छांटकर किया जाता है।
पचेरियर

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

जवाबों:


81

कॉम की कोशिश करो

इसे देखने का दूसरा तरीका:

  • वह लाइनें दिखाएं जो केवल फ़ाइल में मौजूद हैं: (यानी क्या एक से हटा दिया गया था)

    comm -23 a b
    
  • वे पंक्तियाँ दिखाएँ जो केवल फ़ाइल b में मौजूद हैं: (यानी जो b में जोड़ी गई थी)

    comm -13 a b
    
  • वे लाइनें दिखाएं जो केवल एक फ़ाइल या अन्य में मौजूद हैं: (लेकिन दोनों नहीं)

    comm -3 a b | sed 's/^\t//'
    

(चेतावनी: यदि फ़ाइल aमें लाइनें हैं जो TAB से शुरू होती हैं, तो यह (पहले TAB) आउटपुट से हटा दी जाएगी।)

केवल सॉर्ट की गई फ़ाइलें

नोट: दोनों फ़ाइलों commको ठीक से काम करने के लिए हल करने की आवश्यकता है । यदि वे पहले से ही हल नहीं हैं, तो आपको उन्हें छांटना चाहिए:

sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted

यदि फ़ाइलें बहुत लंबी हैं, तो यह काफी बोझ हो सकता है क्योंकि इसके लिए एक अतिरिक्त प्रतिलिपि की आवश्यकता होती है और इसलिए दो बार डिस्क स्थान अधिक होता है।


5
बस यह जोड़ना चाहता था कि इस परिणाम के लिए दोनों फाइलों को हल करने के लिए (केस संवेदनशील) हल करने की आवश्यकता है
मर्मर

आधुनिक पर्याप्त गोले पर, आप कुछ के साथ इन-लाइन को सॉर्ट कर सकते हैं जैसेcomm -12 <(sort a) <(sort b)
जोशुआ ह्यूबर

14

commतुम क्या चाहते हो सकता है। इसके मैन पेज से:

विवरण

क्रमबद्ध फ़ाइलों FILE1 और FILE2 लाइन की तुलना लाइन द्वारा करें।

कोई विकल्प नहीं होने के साथ, तीन-स्तंभ आउटपुट का उत्पादन करें। कॉलम एक में FILE1 के लिए अद्वितीय लाइनें हैं, कॉलम दो में FILE2 के लिए अद्वितीय लाइनें हैं, और कॉलम तीन में दोनों फ़ाइलों के लिए आम लाइनें हैं।

ये कॉलम के साथ suppressable हैं -1, -2और -3क्रमशः।

उदाहरण:

[root@dev ~]# cat a
common
shared
unique

[root@dev ~]# cat b
common
individual
shared

[root@dev ~]# comm -3 a b
    individual
unique

और अगर आप सिर्फ अनोखी लाइनें चाहते हैं और परवाह नहीं करते हैं कि वे किस फाइल में हैं:

[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique

जैसा कि मैन पेज कहता है, फ़ाइलों को पहले से ही क्रमबद्ध किया जाना चाहिए।


9

संदर्भ के बिना परिवर्धन और विलोपन दिखाने के लिए, लाइन नंबर, +, -, <,>! आदि, आप इस तरह से भिन्न का उपयोग कर सकते हैं:

diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt 

उदाहरण के लिए, दो फाइलें दी गई हैं:

a.txt

Common
Common
A-ONLY
Common

b.txt

Common
B-ONLY
Common
Common

निम्न आदेश या तो लाइनों को एक या बी से हटाकर दिखाएंगे:

diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt 

उत्पादन:

B-ONLY
A-ONLY

यह थोड़ा अलग कमांड axt से निकाली गई लाइनों को दिखाएगा:

diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt 

उत्पादन:

A-ONLY

अंत में, यह कमांड a.txt में जोड़ी गई लाइनें दिखाएगा

diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt 

उत्पादन

B-ONLY

2

यही कारण है कि डिफ़ॉल्ट रूप से भिन्न होता है ... शायद आपको व्हाट्सएप को अनदेखा करने के लिए कुछ झंडे जोड़ने की आवश्यकता है?

diff -b -B

रिक्त लाइनों और रिक्त स्थान की विभिन्न संख्याओं को अनदेखा करना चाहिए।


1
नहीं, यह बदल गई रेखाओं के साथ-साथ उन रेखाओं को भी दर्शाता है जिनमें एक वर्ण या चार भिन्न हैं)। मैं ऐसी लाइनें चाहता हूं जो केवल बाएं या दाएं मौजूद हों।
सी। रॉस

2
आप यह तर्क दे सकते हैं कि एक बदले हुए फ़ाइल के अलग-अलग संस्करण केवल बाएँ या दाएँ में मौजूद हैं।
मार्कड्रेटन

2
अलग-अलग (या किसी भी अन्य उपकरण) के लिए कोई रास्ता नहीं है मज़बूती से यह बताने के लिए कि एक बदलाव क्या है, और एक नई लाइन द्वारा प्रतिस्थापित की जाने वाली हटाई गई लाइन क्या है।
सियान

1
तकनीकी रूप से, एक "परिवर्तित" लाइन के रूप में मानती है जैसे कि मूल रेखा को हटा दिया गया था और एक नई रेखा जोड़ी गई थी ... इसलिए तकनीकी रूप से यह आपको केवल जोड़ी गई और हटाए गए लाइनों को दिखा रहा है।
KFro

2

नहीं, diffवास्तव में दो फ़ाइलों के बीच अंतर नहीं दिखाते हैं जिस तरह से कोई सोच सकता है। यह एक उपकरण के लिए संपादन आदेशों का एक क्रम बनाता है जैसे patchकि एक फ़ाइल को दूसरे में बदलने के लिए उपयोग करना।

आप जो भी देख रहे हैं, उसे करने के किसी भी प्रयास के लिए कठिनाई यह है कि परिभाषित कैसे करें कि एक पंक्ति का गठन होता है जो एक हटाए गए बनाम एक जोड़े के बाद बदल गया है। जब एक-दूसरे से सटे लाइनों को जोड़ा, हटाया और बदला जाता है तो क्या करना है।


मेरे विचार से भी। मूल के संशोधन के बजाय इसे नया मानने के लिए एक पंक्ति में कितने प्रतिशत वर्णों को बदलना पड़ता है? तकनीकी रूप से भले ही आपके पास एक चरित्र हो, आप विलोपन और सम्मिलन के बजाय इसे "परिवर्तन" मान सकते हैं।
कामिल किसल

1
मुझे diffसूत्रों को देखे हुए एक लंबा समय हो गया है, लेकिन मुझे लगता है कि दो फाइलों के मिलान में रहने के लिए मिलान करने के लिए ट्रैक के रखने के सभी तरीके याद हैं। लाइनें हैं। लेकिन मुझे कोई भी अंतर-रेखा मिलान याद नहीं है, सिवाय इसके (वैकल्पिक रूप से) सफेद स्थान या मामले को अनदेखा करते हुए। या (शायद) उस शब्द को प्रभावित करते हैं। किसी भी मामले में, यह सब कुछ है patchऔर "vgrep" बस सवारी के लिए आता है। शायद। मंगलवार को।
डेनिस विलियमसन

2

दृश्य तुलना उपकरण दो फ़ाइलों को एक साथ फिट करते हैं ताकि एक ही संख्या में लाइनों के साथ एक खंड लेकिन अलग सामग्री को एक परिवर्तित खंड माना जाएगा। मेल खाने वाले सेगमेंट के बीच पूरी तरह से नई लाइनों को जोड़ा सेगमेंट माना जाता है।

यह भी है कि sdiff कमांड-लाइन टूल कैसे काम करता है, जो एक टर्मिनल में दो फाइलों की साइड-बाय-साइड तुलना दिखाता है। बदली हुई रेखाएं अलग हो जाती हैं | चरित्र। यदि कोई लाइन केवल फ़ाइल A में मौजूद है, तो <का उपयोग विभाजक वर्ण के रूप में किया जाता है। यदि कोई लाइन केवल फ़ाइल B में मौजूद है, तो> विभाजक के रूप में उपयोग की जाती है। यदि आपके पास फ़ाइलों में <और> अक्षर नहीं हैं, तो आप इसका उपयोग केवल जोड़े गए लाइनों को दिखाने के लिए कर सकते हैं:

sdiff A B | grep '[<>]'

2

धन्यवाद सेरनवी, आपके समाधान (वोट नहीं दिया गया) ने वास्तव में मुझे वास्तव में वही दिया जो मैं एक टन पृष्ठों पर उम्र की तलाश में था।

आपके उत्तर का उपयोग करते हुए, यहां मैं वही हूं जो चीजों की सूची को बदलने / जोड़ने / हटाने के लिए आया था। उदाहरण / etc / passwd फ़ाइल के 2 संस्करणों का उपयोग करता है और संबंधित रिकॉर्ड के लिए उपयोगकर्ता नाम प्रिंट करता है।

#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'

ध्यान दें कि क्योंकि "एक रेखा को संशोधित किया गया है" और "एक रेखा को हटा दिया गया है और इसके नीचे या उससे ऊपर एक और रेखा जोड़ दी गई है" शब्दार्थ है। एक सामान्य पाठ आधारित भिन्न उपकरण उन मामलों को अलग नहीं कर सकता है। परिणामस्वरूप, आपका sdiff आधारित उत्तर मज़बूती से सभी मामलों के लिए काम नहीं कर सकता है।
मिकको रेंटालिनेन

0

मुझे यह विशेष रूप अक्सर उपयोगी लगता है:

diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g

उदाहरण:

printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
     --new-line-format=$'+%l\n' \
     --unchanged-line-format='' \
     f g

आउटपुट:

-b
-c
+B
+C
-e
-f
+E
+F

तो यह पुरानी लाइनों को दिखाता है, -जिसके तुरंत बाद संबंधित नई लाइन होती है +

यदि हमारा कोई विलोपन था C:

printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
     --new-line-format=$'+%l\n' \
     --unchanged-line-format='' \
     f g

यह इस तरह दिख रहा है:

-b
+B
+C
-e
-f
+E
+F

प्रारूप में प्रलेखित है man diff:

       --line-format=LFMT
              format all input lines with LFMT`

तथा:

       LTYPE is 'old', 'new', or 'unchanged'.
              GTYPE is LTYPE or 'changed'.

तथा:

              LFMT (only) may contain:

       %L     contents of line

       %l     contents of line, excluding any trailing newline

       [...]

संबंधित प्रश्न: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux

उबंटू 18.04 में परीक्षण किया गया।


-1

file1:

text670_1
text067_1
text067_2

करें 2:

text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1

उपयोग:

diff -y file1 file2

यह पश्चाताप फ़ाइलों के लिए दो कॉलम दिखाती है।

आउटपुट:

text670_1                           
                                  > text04_1
                                  > text04_2
                                  > text05_1
                                  > text05_2
text067_1                           text67_1
text067_2                           text67_2
                                  > text1000_1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.