Grep के साथ सटीक स्ट्रिंग का पता लगाएं


9

उदाहरण के अनुसार, मैंने कई ईमेल पते के साथ एक बड़ी पाठ फ़ाइल की है, जिसमें bash का उपयोग करके मुझे खोज / सत्यापित करने की आवश्यकता है कि कोई ईमेल मौजूद है (या नहीं)। का उपयोग किया जाना चाहिए (केवल) "एंकर"?

grep '^user1@example.com' text_file

या बेहतर तरीके हैं? मुझे बैश स्क्रिप्ट बनाने की जरूरत है और मैं सुरक्षित रहना चाहूंगा।


1
क्या ईमेल एक लाइन का एकमात्र शब्द है?
ग्लेन जैकमैन

वास्तव में: फ़ाइल में यह प्रारूप है: user1@example.com example.com/user1
Pol Hallen

1
उस स्थिति में, मैं उपयोग करूंगा grep -q '^user1@example\.com\>'- शुरुआत में एक लाइन एंकर के साथ, और अंत में एक शब्द-एंकर।
ग्लेन जैकमैन

जवाबों:


24

-Fनियमित अभिव्यक्ति के विपरीत (निश्चित स्ट्रिंग, देखें ) और -x(सटीक: पूरी रेखा से मेल खाते) विकल्प।

grep -Fx user1@example.com text_file

के बराबर होगा:

grep '^user1@example\.com$' text_file

(याद रखें कि .एक नियमित अभिव्यक्ति ऑपरेटर है जो किसी भी चरित्र से मेल खाता है)।

-qविकल्प का उपयोग करें यदि आप केवल जाँच करना चाहते हैं कि क्या ऐसी कोई रेखा है:

grep -Fxq user1@example.com text_file &&
  echo yes, that address is in that file.

यदि खोज करने के लिए लाइन और फ़ाइल का नाम परिवर्तनशील है:

grep -Fxqe "$email" < "$file"

या

grep -Fxq -- "$email" < "$file"

आप नहीं चाहते:

grep -Fxq "$email" "$file"

के रूप में अगर समस्याओं का कारण होगा $emailया के $fileसाथ शुरू कर दिया -

यदि फ़ाइल (आपके वर्तमान स्थान में, अधिमानतः C) सॉर्ट की जाती है , तो आप संभवतः commइसके बजाय का उपयोग करके चीजों को गति दे सकते हैं grep:

printf '%s\n' user1@example.com | comm -12 - text_file

आपके द्वारा जांच के लिए कई ईमेल पते होने पर (उदाहरण के लिए किसी अन्य सॉर्ट की गई फ़ाइल में) लाभ अधिक स्पष्ट हो जाएगा:

comm -12 text_file emails_to_check

इससे तेज़ होगा:

grep -Fxf emails_to_check text_file

AFAIK, grep -Fxq -- "$email" "$file"भी काम करता है।
vinc17

स्टीफन, आपने <रीडायरेक्टर का उपयोग करके एक फ़ाइल इनपुट (grep द्वारा नियंत्रित) से स्विच करने के लिए स्विच क्यों किया ? क्या कोई फायदे हैं?
umläute

@ umläute और vinc17। जैसा कि मैंने कहा, यह शुरू होने वाले फ़ाइल नाम के लिए कवर करना है -। यहां तक कि grep -- "$email" "$file"कहा जाता है एक फ़ाइल के लिए एक समस्या हो सकता है -(जो grepविशेष रूप से अर्थ के रूप में व्यवहार करता है stdin )
स्टीफन Chazelas

6

जितना संभव हो उतना कुशल होने के लिए, आप पहला मैच मिलने के बाद रोकना चाहते हैं। यदि आपके पास GNU है grep, तो आप यह कर सकते हैं:

grep -m 1 '^user1@example\.com$' your_file

यदि आप नहीं करते हैं, तो आप पर्ल का उपयोग कर सकते हैं:

perl -nlE 'say and last if $_ eq q{user1@example.com}' your_file

4
-mजीएनयू विशिष्ट है। -qयदि आप कुशलतापूर्वक जाँच करना चाहते हैं कि ऐसी कोई रेखा है तो POSIX का उपयोग करें ।
स्टीफन चेज़लस

3

वहां बहुत सारे ईमेल चेक होते हैं। उनमें से एक है:

grep -E -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" text_file

मेरा उत्तर विस्तृत करने के लिए।

आप ^एंकर का उपयोग कर रहे हैं जो स्ट्रिंग की शुरुआत को इंगित करता है। यदि एक ईमेल पता लंबे स्ट्रिंग के बीच कहीं है तो यह मेल नहीं खाएगा।


2
धन्यवाद। यह एक फ़ाइल के अंदर सभी ईमेल पते को "निकालने" के लिए एक सामान्य grep विकल्प है। मुझे पढ़ने के लिए ईमेल के माध्यम से एक-एक ईमेल पते की तलाश करनी चाहिए, फिर इसे जांचने के लिए grep का उपयोग करना चाहिए।
पोल हॉलेन

2

आपकी grepकमांड उस सभी चीज़ों से मेल खाएगी ^user1@example.com, जो ईमेल पते के साथ ही शुरू होती है, लेकिन यह भी user1@example.com.spammer.com। चूंकि .नियमित अभिव्यक्तियों में एक विशेष चरित्र है जो किसी भी कुंजी से मेल खाता है, इसलिए आपको इसे बचना चाहिए\.

यह मानते हुए कि आपके टेक्स्टफाइल में प्रति पंक्ति एक पता है, उपयोग करें:

EMAIL=user1@example\\.com
egrep "^${EMAIL}$" text_file

अनुगामी $यह सुनिश्चित करेगी कि ईमेल-पता के बाद लाइन समाप्त हो जाए। मैं दोहरे उद्धरण चिह्नों का उपयोग कर रहा हूं ", क्योंकि ये चर (सिंगल-कोट्स के विपरीत ') का उपयोग करने की अनुमति देते हैं


1
वह भी मेल खाता है user1@example-com
स्टीफन चेजालस

@ स्टीफेनचैलेज आप निश्चित रूप से सही हैं; उत्तर को अद्यतन किया।
umläute

@ umläute आपको बैकस्लैश को दोगुना करने की आवश्यकता है। लेकिन इसका इस्तेमाल करना बेहतर है -Fx
vinc17

@ vinc17, दोह; मारना बचना; किसी भी तरह, हाँ मैं सहमत हूँ कि यह उपयोग करने के लिए बेहतर है, -Fxलेकिन यह
स्टीफन

0

सामान्य शाब्दिक / सटीक स्ट्रिंग मैच को ध्यान में रखते हुए:

grep -w "search_word" <file>  >  output.txt

#\b shows boundaries over here.

या,

 grep  "\bsearch_word\b"  <file>  >  output.txt 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.