"Ungrep" - कौन से पैटर्न मेल नहीं खाते हैं


13

मैं निम्नलिखित करने के लिए एक कमांड या स्क्रिप्ट की तलाश में हूँ -

file1.txt:

abcd
efgh 
ijkl
mnop

file2.txt:

123abcd123
123efgh123
123mnop123

मुझे एक कमांड चाहिए जो कुछ इस तरह से करे:

ungrep file1.txt file2.txt

और निम्नलिखित लौटाता है:

ijkl

दूसरे शब्दों में यह मुझे file1.txt में ऐसी लाइनें दे रहा है जो file2.txt के grep पर कोई परिणाम नहीं लौटाएंगी। मुझे पता है कि मैं file1.txt के माध्यम से पुनरावृत्ति करके ऐसा कर सकता हूं, प्रत्येक पंक्ति के लिए file2.txt को grepping कर रहा है और परिणाम को संग्रहीत कर रहा है, और किसी भी रेखा को आउटपुट कर रहा है जहां परिणाम रिक्त है, लेकिन मैं ऐसा करने के लिए अधिक कुशल तरीके की उम्मीद कर रहा था।

जवाबों:


18

GNU grepके साथ निम्नलिखित कार्य करना चाहिए। -fविकल्प का उपयोग करते हुए , file1.txt"पैटर्न फ़ाइल" के रूप में पास करें - लेकिन इसे डेटा फ़ाइल के रूप में दूसरी बार भी पास करें। -oकेवल मिलान भागों की रिपोर्ट करने के लिए उपयोग करें । अंत में उन शब्दों को निकालता है जो केवल एक बार मेल खाते हैं - ये उन पंक्तियों से file1.txtमेल खाते हैं जिनसे मैच नहीं मिलता है file2.txt

grep -h -o -f  file1.txt file2.txt file1.txt | sort | uniq -u
ijkl

बहुत अच्छा वर्णन। धन्यवाद और +1।
unxnut

4
आप grep की चालबाजी के बिना एक ही प्रभाव प्राप्त कर सकते हैं: sort file1.txt <(grep -of file1.txt file2.txt) | uniq -uलेकिन, आपके समाधान की तरह, यह केवल तभी काम करता है जब पैटर्न फ़ाइल में वास्तव में कोई भी रेगेक्स मेटाचैकर नहीं होता है।
रिसी

@rici, यह एक बहुत अच्छी बात है
iruvar

2
सुधार:grep -oFf file1.txt file2.txt | sort file1.txt - | uniq -u
स्टीफन चेज़लस

10

आप इसे इस awkतरह से कर सकते हैं :

awk '
  NR == FNR {w[$0]; next}
  {for (i in w) if (index($0,i)) delete w[i]}
  END {for (i in w) print i}' file1.txt file2.txt

उपयोग करके index, हम नियमित अभिव्यक्तियों के मिलान के बजाय सबस्ट्रिंग की तलाश कर रहे हैं।

क्योंकि हम शब्द को शब्द से हटाते हैं, जैसे ही हमें कोई मेल मिलता है, हम अनावश्यक खोजों से बच जाते हैं।


1
मैं केवल इसे स्वीकार करूंगा। यह किसी भी O (n लॉग एन) सॉर्टिंग को लागू नहीं करता है, और अजीब रूप से विफल नहीं होता है जब पैटर्न में regex मेटा-वर्ण होते हैं, और regexes का समर्थन करने के लिए बढ़ाया जा सकता है।
कज़

मुझे विश्वास नहीं हो रहा है कि केवल मूल्यांकन w[$0]करने से सरणी को कुंजी जोड़ने का दुष्प्रभाव होता है।
कज़

1
@ काज़, हाँ जो भ्रामक हो सकता है, और आप कई लिपियों को जान-बूझकर सरणी तत्वों को अनायास आवंटित नहीं कर सकते हैं if (a[$1])बजाय if ($1 in a)उदाहरण के। यह awkमूल सहित हर का मामला है awkऔर nawk, लेकिन कल मानक को देखते हुए, मैं इसे निर्दिष्ट नहीं कर पाया।
स्टीफन चेज़लस

1
@Kaz यहाँ POSIX उद्धरण है: "आवेदन यह सुनिश्चित करेगा कि के साथ प्रयोग किया एक बहु dimensioned सूचकांक में ऑपरेटर parenthesized है। में ऑपरेटर, जो एक विशेष सरणी तत्व के अस्तित्व के लिए परीक्षण, कारण यह है कि तत्व मौजूद नहीं करेगा कोई। एक गैर-स्थिर सरणी तत्व के अन्य संदर्भ स्वचालित रूप से इसे बनाएंगे। " यहां से एक पैराग्राफ या दो ऊपर स्क्रॉल करके इसे पाया जा सकता है
jw013

1
जब तक file1विशाल नहीं है (कुछ मूल्य के लिए विशाल), मैं इस समाधान को पसंद करूंगा क्योंकि इसमें किसी भी प्रकार की आवश्यकता नहीं होती है file2और बहुत अधिक कुशल होने की उम्मीद की जाएगी।
jw013
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.