जवाबों:
के अलावा एक उपकरण जाने 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/==1
ir 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
, -f
POSIX की आवश्यकता के रूप में) में है /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\}\)+
? (२) क्या होगा यदि एक शब्द / पैटर्न एक पंक्ति में एक से अधिक बार दिखाई देता है (और दूसरा नहीं दिखाई देता है)? क्या यह शब्द एक बार आने वाले शब्द के बराबर है, या क्या यह कई घटनाओं के रूप में गिना जाता है?