क्या कोई ऐसा उपकरण है जो ए को फाइल करने वाली लाइनें प्राप्त कर सकता है, लेकिन फाइल बी नहीं है? मैं, उदाहरण के लिए, के साथ एक छोटी सी सरल स्क्रिप्ट बना सकता है, लेकिन अगर ऐसा कुछ पहले से मौजूद है, तो मैं अभी से अपना समय बचाऊंगा।
क्या कोई ऐसा उपकरण है जो ए को फाइल करने वाली लाइनें प्राप्त कर सकता है, लेकिन फाइल बी नहीं है? मैं, उदाहरण के लिए, के साथ एक छोटी सी सरल स्क्रिप्ट बना सकता है, लेकिन अगर ऐसा कुछ पहले से मौजूद है, तो मैं अभी से अपना समय बचाऊंगा।
जवाबों:
हाँ। grep
टेक्स्ट स्ट्रिंग्स के लिए फ़ाइलों की खोज करने के लिए मानक टूल का उपयोग एक फ़ाइल से दूसरे में सभी पंक्तियों को घटाने के लिए किया जा सकता है।
grep -F -x -v -f fileB fileA
यह फाइलबी में प्रत्येक लाइन को एक पैटर्न के रूप में उपयोग करके काम करता है ( -f fileB
) और इसे एक सादे स्ट्रिंग के रूप में मैच करने के लिए (नियमित रेगेक्स नहीं) ( -F
) के रूप में मानता है । आप मैच को पूरी लाइन ( -x
) पर होने के लिए मजबूर करते हैं और केवल उन लाइनों को प्रिंट करते हैं जो मेल नहीं खाते ( -v
)। इसलिए आप फ़ाइलए में उन पंक्तियों को प्रिंट कर रहे हैं जिनमें फ़ाइलबी में कोई भी डेटा नहीं है।
इस समाधान का नकारात्मक पक्ष यह है कि यह लाइन ऑर्डर को ध्यान में नहीं रखता है और यदि आपके इनपुट में अलग-अलग जगहों पर डुप्लिकेट लाइनें हैं, तो आपको वह नहीं मिल सकता है जो आप अपेक्षा करते हैं। इसका समाधान वास्तविक तुलना उपकरण जैसे कि उपयोग करना है diff
। आप फ़ाइल में 100% लाइनों पर संदर्भ मूल्य के साथ एक अलग फ़ाइल बनाकर ऐसा कर सकते हैं, फिर इसे केवल उन पंक्तियों के लिए पार्स कर रहे हैं जो फ़ाइल बी को फ़ाइल बी में परिवर्तित करने पर हटा दी जाएगी (ध्यान दें कि यह कमांड भी अंतर को हटा देता है। सही लाइनों को प्राप्त करने के बाद प्रारूपण करना।)
diff -U $(wc -l < fileA) fileA fileB | sed -n 's/^-//p' > fileC
-u
तर्क वास्तव में किसी संख्या के पैरामीटर को तब तक लेता है जब तक कि वह किसी स्थान का अनुसरण नहीं करता है। मेरे पास पहले के तरीके का लाभ यह है कि यह मूल्य के साथ या उसके बिना काम करेगा, इसलिए आप उस उप कमांड रूटीन में कुछ का उपयोग कर सकते हैं जो आउटपुट नहीं लौटा। दूसरी ओर ऊपरी मामले '-यू' के लिए एक तर्क की आवश्यकता होती है।
diff
पाइपलाइन इलाज धन्यवाद काम करता है।
grep
। उदाहरण:grep -F -x -v -f <(sort fileB) <(sort fileA)
diff
का लाभ यह है कि फ़ाइल में स्थिति को ध्यान में रखा जाता है।
उत्तर आपके द्वारा तुलना की जा रही फ़ाइलों के प्रकार और प्रारूप पर बहुत अधिक निर्भर करता है।
यदि आप जिन फाइलों की तुलना कर रहे हैं, वे पाठ फाइलें छांट रहे हैं, तो रिचर्ड स्टालमैन और डेविद मैकेंजी द्वारा लिखित जीएनयू उपकरण आपके द्वारा comm
किए जाने वाले फ़िल्टरिंग का प्रदर्शन कर सकते हैं। यह कोरुटिल्स का हिस्सा है।
कहो कि आपके पास निम्न 2 फाइलें हैं:
$ cat a
1
2
3
4
5
$ cat b
1
2
3
4
5
6
फ़ाइल में वे पंक्तियाँ जो फ़ाइल b
में नहीं हैं a
:
$ comm <(sort a) <(sort b) -3
6
comm
; दुर्भाग्य से, comm
सॉर्ट की गई फ़ाइलों की आवश्यकता है
<()
? यह काम करता है और मैं इसे प्राप्त करता हूं, लेकिन क्या इस अजीबता का कोई नाम है?
comm
मूल रूप से बेल लैब्स में किसी के द्वारा 1973 में सर्कस लिखा गया था, आरएमएस पर नहीं। आप GNU कार्यान्वयन की बात कर रहे हैं जो बहुत बाद में आया। वर्षों में यूनिक्स उपयोगिताओं के कई अलग-अलग कार्यान्वयन हुए हैं।
से stackoverflow ...
comm -23 file1 file2
-23 उन फ़ाइलों को दबाता है जो दोनों फ़ाइलों में हैं, या केवल फ़ाइल 2 में हैं। फ़ाइलों को क्रमबद्ध किया जाना है (वे आपके उदाहरण में हैं) लेकिन यदि नहीं, तो उन्हें पहले सॉर्ट के माध्यम से पाइप करें ...
मैन पेज यहाँ देखें
ग्रीप और कॉम (सॉर्ट के साथ) तरीके बड़ी फ़ाइलों पर लंबा समय लेते हैं । Stack ओवरफ्लो पर दो फ़ाइलों में से एक के लिए अद्वितीय लाइनों को निकालने के लिए SiegeX और ghostdog74 ने दो महान awk विधियाँ साझा कीं :
$ awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2
$ awk 'FNR==NR{a[$0]++;next}(!($0 in a))' file1 file2
यदि फ़ाइलें बड़ी हैं और आपके पास अपनी प्रविष्टियों के लिए कोई कस्टम ऑर्डर नहीं है, तो grep को बहुत लंबा समय लगता है। एक त्वरित विकल्प होगा
sort file1 > 1
sort file2 > 2
diff 1 2 | grep "\>" | sed -e 's/> //'
[file2-file1 परिणाम स्क्रीन, फाइल करने के लिए पाइप आदि]
बदलने के >
लिए <
विपरीत घटाव प्राप्त होगा।rm 1 2