2012-06-22 16 views
19

ठीक है, मैं पाठ फ़ाइलों में मेरी linux बॉक्स पर दो संबंधित सूचियों है:बैश - दो सूचियों के बीच अंतर

/tmp/oldList 
/tmp/newList 

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

+0

उसी प्रश्न को 4 दिन पहले पूछा गया था http://stackoverflow.com/questions/11099894/comparing-2-unsorted-lists-in-linux-listing-the-unique-in-the-second-file/11101143 # 11101143 –

उत्तर

50

दो फ़ाइलों की तुलना करने के comm(1) आदेश का उपयोग करें। उन्हें दोनों को सॉर्ट करने की आवश्यकता है, जो आप बड़े होते हैं, यदि आप बड़े होते हैं, या आप इसे प्रक्रिया प्रतिस्थापन के साथ इनलाइन कर सकते हैं।

comm झंडे -1, -2 और -3 यह दर्शाता है जो फ़ाइल से लाइनों (1 दायर करने के लिए अद्वितीय, 2 दायर करने के लिए अद्वितीय या दोनों के लिए आम) को दबाने के लिए का एक संयोजन ले सकते हैं।

केवल पुराने फ़ाइल की पंक्तियों को प्राप्त करने के लिए:

comm -13 <(sort /tmp/oldList) <(sort /tmp/newList) 

आप एक while read पाश प्रत्येक पंक्ति को संसाधित करने में फ़ीड कर सकते हैं कि:

comm -23 <(sort /tmp/oldList) <(sort /tmp/newList) 

केवल नए फ़ाइल की पंक्तियों को प्राप्त करने के लिए :

while read old ; do 
    ...do stuff with $old 
done < <(comm -23 <(sort /tmp/oldList) <(sort /tmp/newList)) 

और इसी तरह नई लाइनों के लिए।

4

diff command आपके लिए तुलना करेगा।

जैसे

$ diff /tmp/oldList /tmp/newList 

अधिक जानकारी के लिए ऊपर आदमी पेज लिंक देखें। यह आपकी समस्या के अपने पहले भाग का ख्याल रखना चाहिए।

+1

मैं केवल इतना जोर दूंगा कि 'diff' कमांड में आउटपुट स्वरूपण के लिए विकल्पों की एक हास्यास्पद संख्या है, जो इस कार्यक्रम को सुविधाजनक इनपुट प्रदान कर सकती है जो मतभेदों को संसाधित करेगी। – chepner

+0

@chepner अच्छा बिंदु .. यह निश्चित रूप से लिंक किए गए मैन पेज को देखने लायक है। – Levon

0

आप की कोशिश की diff

$ diff /tmp/oldList /tmp/newList 

$ man diff 
2

आपकी स्क्रिप्ट को पठनीयता की आवश्यकता होने पर रूबी का उपयोग करने पर विचार करें।

केवल पुराने फ़ाइल की पंक्तियों को प्राप्त करने के लिए:

ruby -e "puts File.readlines('/tmp/newList') - File.readlines('/tmp/oldList')" 

आप फ़ीड कर सकते हैं कि एक समय में प्रत्येक कार्रवाई करने के लिए लूप पढ़ें:

ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')" 

केवल नए फ़ाइल की पंक्तियों को प्राप्त करने के लिए लाइन:

while read old ; do 
    ...do stuff with $old 
done < ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')" 
1

यह पुराना है, लेकिन पूर्णता के लिए हमें यह कहना चाहिए कि यदि आपके पास वास्तव में एक बड़ा सेट है, तो उपवास टी समाधान diff उपयोग करने के लिए एक स्क्रिप्ट उत्पन्न करने के लिए और उसके बाद स्रोत यह, इस तरह होगा: के रूप में नष्ट और कहा

#!/bin/bash 

line_added() { 
    # code to be run for all lines added 
    # $* is the line 
} 

line_removed() { 
    # code to be run for all lines removed 
    # $* is the line 
} 

line_same() { 
    # code to be run for all lines at are the same 
    # $* is the line 
} 

cat /tmp/oldList | sort >/tmp/oldList.sorted 
cat /tmp/newList | sort >/tmp/newList.sorted 

diff >/tmp/diff_script.sh \ 
    --new-line-format="line_added %L" \ 
    --old-line-format="line_removed %L" \ 
    --unchanged-line-format="line_same %L" \ 
    /tmp/oldList.sorted /tmp/newList.sorted 

source /tmp/diff_script.sh 

लाइन्स बदल दिखाई देगा। यदि आपको यह पसंद नहीं है, तो आप --changed-group-format का उपयोग कर सकते हैं। Diff मैन्युअल पृष्ठ की जांच करें।

संबंधित मुद्दे