जवाबों:
के अलावा एक उपकरण जाने grepका रास्ता है।
उदाहरण के लिए, पर्ल का उपयोग करना, यह होगा:
perl -ne 'print if /pattern1/ xor /pattern2/'
perl -neस्टड की प्रत्येक पंक्ति पर दी गई कमांड को चलाता है, जो इस मामले में लाइन को प्रिंट करता है यदि यह मेल खाता है /pattern1/ xor /pattern2/, या दूसरे शब्दों में एक पैटर्न से मेल खाता है , लेकिन अन्य (अनन्य या) नहीं।
यह या तो क्रम में पैटर्न के लिए काम करता है, और इसके कई आवृत्तियों की तुलना में बेहतर प्रदर्शन होना चाहिए grep, और साथ ही कम टाइपिंग है।
या, इससे भी कम, awk के साथ:
awk 'xor(/pattern1/,/pattern2/)'
या जाग के संस्करणों के लिए जो नहीं है xor:
awk '/pattern1/+/pattern2/==1`
xorकेवल GNU Awk में उपलब्ध है?
/pattern1/+/pattern2/==1ir xorयाद आ रही है।
\b) को स्वयं पैटर्न में रख सकते हैं, अर्थात \bword\b।
के साथ प्रयास करें egrep
egrep 'pattern1|pattern2' file | grep -v -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
grep -e foo -e bar | grep -v -e 'foo.*bar' -e 'bar.*foo'
Direct invocation as either egrep or fgrep is deprecated- पसंद करेंgrep -E
-fऔर -eविकल्प होने चाहिए, हालांकि पुराने egrepऔर fgrepथोड़ी देर के लिए समर्थित रहेंगे।
grep(है कि समर्थन करता है -F, -E, -e, -fPOSIX की आवश्यकता के रूप में) में है /usr/xpg4/bin। उपयोगिताओं में विशिष्ट /binहैं।
उन grepकार्यान्वयनों के साथ, जो प्रति-सदृश नियमित अभिव्यक्तियों (जैसे pcregrepया GNU या अस्सिटेंट-ओपन grep -P) का समर्थन करते हैं, आप इसे एक grepइनवोकेशन में कर सकते हैं :
grep -P '^(?=.*pat1)(?!.*pat2)|^(?=.*pat2)(?!.*pat1)'
यह उन रेखाओं को खोजता है जो मेल खाती हैं pat1लेकिन नहीं pat2, या pat2नहीं pat1।
(?=...)और (?!...)क्रमशः आगे देखो और नकारात्मक देखो आगे ऑपरेटरों। इसलिए तकनीकी रूप से, उपरोक्त विषय की शुरुआत के लिए दिखता है ( ^) बशर्ते इसके बाद .*pat1और इसके बाद .*pat2या इसके साथ pat1और pat2उलट न हो।
यह लाइनों के लिए उप-रूपी है जिसमें दोनों पैटर्न होते हैं क्योंकि उन्हें फिर दो बार देखा जाएगा। आप इसके बजाय अधिक उन्नत पर्ल ऑपरेटरों का उपयोग कर सकते हैं:
grep -P '^(?=.*pat1|())(?(1)(?=.*pat2)|(?!.*pat2))'
(?(1)yespattern|nopattern)मैच के खिलाफ yespatternअगर 1सेंट पर कब्जा समूह ( ()ऊपर खाली ) मिलान किया, और nopatternअन्यथा। यदि वह ()मेल खाता है, तो इसका मतलब है कि मिलान pat1नहीं हुआ है, इसलिए हम खोज करते हैं pat2(सकारात्मक रूप से आगे देखें), और हम अन्यथा नहीं pat2 खोजते हैं (नकारात्मक रूप से आगे देखें)।
इसके साथ sed, आप इसे लिख सकते हैं:
sed -ne '/pat1/{/pat2/!p;d;}' -e '/pat2/p'
grep: the -P option only supports a single patternकम से कम हर उस प्रणाली पर विफल हो जाता है जिसकी मुझे पहुँच है। आपके दूसरे समाधान के लिए +1, हालाँकि।
grep। pcregrepऔर ast- खुले grep में वह समस्या नहीं है। मैंने -eवैकल्पिक आरई ऑपरेटर के साथ कई को बदल दिया है , इसलिए इसे जीएनयू के grepसाथ भी काम करना चाहिए ।
बूलियन शब्दों में, आप A xor B की तलाश में हैं, जिसे लिखा जा सकता है
(ए और बी नहीं)
या
(बी और ए नहीं)
यह देखते हुए कि आपके प्रश्न का उल्लेख नहीं है कि आप आउटपुट के क्रम से संबंधित हैं, जब तक कि मिलान लाइनें दिखाई जाती हैं, A xor B का बूलियन विस्तार grep में बहुत सरल है:
$ cat << EOF > foo
> a b
> a
> b
> c a
> c b
> b a
> b c
> EOF
$ grep -w 'a' foo | grep -vw 'b'; grep -w 'b' foo | grep -vw 'a';
a
c a
b
c b
b c
sort | uniq।
निम्नलिखित उदाहरण के लिए:
# Patterns:
# apple
# pear
# Example line
line="a_apple_apple_pear_a"
यह विशुद्ध रूप से साथ किया जा सकता grep -E, uniqऔर wc।
# Grep for regex pattern, sort as unique, and count the number of lines
result=$(grep -oE 'apple|pear' <<< $line | sort -u | wc -l)
यदि grepपर्ल नियमित अभिव्यक्तियों के साथ संकलित किया गया है, तो आप पाइप की आवश्यकता के बजाय अंतिम घटना पर मेल कर सकते हैं uniq:
# Grep for regex pattern and count the number of lines
result=$(grep -oP '(apple(?!.*apple)|pear(?!.*pear))' <<< $line | wc -l)
परिणाम का परिणाम:
# Only one of the words exists if the result is < 2
((result > 0)) &&
if (($result < 2)); then
echo Only one word matched
else
echo Both words matched
fi
एक-लाइनर:
(($(grep -oP '(apple(?!.*apple)|pear(?!.*pear))' <<< $line | wc -l) == 1)) && echo Only one word matched
यदि आप पैटर्न को हार्ड-कोड नहीं करना चाहते हैं, तो तत्वों के एक चर सेट के साथ इसे एक फ़ंक्शन के साथ स्वचालित किया जा सकता है।
यह मूल रूप से बश में पाइप या अतिरिक्त प्रक्रियाओं के बिना एक फ़ंक्शन के रूप में किया जा सकता है, लेकिन अधिक शामिल होगा और संभवतः आपके प्रश्न के दायरे से बाहर है।
Big apple\nऔर pear-shaped\n, तो आउटपुट में उन दोनों लाइनें शामिल होनी चाहिए। आपके समाधान को 2 की गिनती मिलेगी; लंबे संस्करण की रिपोर्ट "दोनों शब्दों से मेल खाती है" (जो कि गलत प्रश्न का उत्तर है) और लघु संस्करण कुछ भी नहीं कहेंगे। (३) एक सुझाव: -oयहां उपयोग करना वास्तव में एक बुरा विचार है, क्योंकि यह उन रेखाओं को छिपाता है जिनमें मैच होते हैं, इसलिए आप यह नहीं देख सकते हैं कि दोनों शब्द एक ही लाइन पर दिखाई देते हैं। ... (Cont'd)
uniq/ sort -uऔर फैंसी पर्ल नियमित अभिव्यक्ति वास्तव में इस सवाल का जवाब एक उपयोगी तक जोड़ नहीं है प्रत्येक पंक्ति पर केवल पिछले घटना मैच के लिए। लेकिन, अगर उन्होंने ऐसा किया, तब भी यह एक बुरा जवाब होगा क्योंकि आप यह नहीं समझाते हैं कि वे सवाल का जवाब देने में कैसे योगदान करते हैं। ( एक अच्छी व्याख्या के उदाहरण के लिए स्टीफन चेज़ेलस का उत्तर देखें ।)
[a-z][a-z0-9]\(,7\}\(\.[a-z0-9]\{,3\}\)+? (२) क्या होगा यदि एक शब्द / पैटर्न एक पंक्ति में एक से अधिक बार दिखाई देता है (और दूसरा नहीं दिखाई देता है)? क्या यह शब्द एक बार आने वाले शब्द के बराबर है, या क्या यह कई घटनाओं के रूप में गिना जाता है?