मैं एक लाइन को फ़िल्टर करने का एक तरीका खोजने की कोशिश कर रहा हूं जिसमें "नींबू" और "चावल" शब्द है। मुझे पता है कि "नींबू" या "चावल" कैसे मिलेंगे लेकिन उनमें से दो नहीं। उन्हें दूसरे के बगल में होने की आवश्यकता नहीं है, केवल एक ही पंक्ति का पाठ।
मैं एक लाइन को फ़िल्टर करने का एक तरीका खोजने की कोशिश कर रहा हूं जिसमें "नींबू" और "चावल" शब्द है। मुझे पता है कि "नींबू" या "चावल" कैसे मिलेंगे लेकिन उनमें से दो नहीं। उन्हें दूसरे के बगल में होने की आवश्यकता नहीं है, केवल एक ही पंक्ति का पाठ।
जवाबों:
"एक ही पंक्ति पर दोनों" का अर्थ है "'चावल' के बाद बेतरतीब अक्षर और उसके बाद 'नींबू' या दूसरा तरीका"।
रेगेक्स में जो है rice.*lemon
या lemon.*rice
। आप एक का उपयोग कर गठबंधन कर सकते हैं |
:
grep -E 'rice.*lemon|lemon.*rice' some_file
यदि आप विस्तारित लोगों के बजाय सामान्य रेगेक्स का उपयोग करना चाहते हैं ( -E
तो आपको इससे पहले एक बैकस्लैश की आवश्यकता होगी |
:
grep 'rice.*lemon\|lemon.*rice' some_file
अधिक शब्दों के लिए जो जल्दी से थोड़ा लंबा हो जाता है और आमतौर पर grep
उदाहरण के लिए, कई कॉल का उपयोग करना आसान होता है :
grep rice some_file | grep lemon | grep chicken
grep rice
युक्त लाइनों को पाता है rice
। यह खिलाया जाता है grep lemon
जिसमें केवल नींबू युक्त रेखाएँ मिलेंगी .. और इसी तरह। जबकि ओपी - और साथ ही आपके पूर्व जवाब - किसी भी [चावल | नींबू | चिकन] की अनुमति दे रहे हैं
|
भाग जाने की आवश्यकता क्यों है grep
? धन्यवाद!
egrep
विस्तारित रेगेक्स का उपयोग करता है जहां |
OR तर्क के रूप में समझा जाता है। grep
मूलभूत रेगेक्स के लिए चूक, जहां \|
OR है
grep
'मैनपेज' egrep
को हटा दिया गया है और इसे बदल दिया जाना चाहिए grep -E
। मैंने तदनुसार उत्तर संपादित करने की स्वतंत्रता ली।
आप पहले grep कमांड के आउटपुट को दूसरे grep कमांड पर पाइप कर सकते हैं और यह दोनों पैटर्न से मेल खाएगा। तो, आप कुछ ऐसा कर सकते हैं:
grep <first_pattern> <file_name> | grep <second_pattern>
या,
cat <file_name> | grep <first_pattern> | grep <second_pattern>
आइए हमारी फ़ाइल में कुछ सामग्री जोड़ें:
$ echo "This line contains lemon." > test_grep.txt
$ echo "This line contains rice." >> test_grep.txt
$ echo "This line contains both lemon and rice." >> test_grep.txt
$ echo "This line doesn't contain any of them." >> test_grep.txt
$ echo "This line also contains both rice and lemon." >> test_grep.txt
फ़ाइल में क्या है:
$ cat test_grep.txt
This line contains lemon.
This line contains rice.
This line contains both lemon and rice.
This line doesn't contain any of them.
This line also contains both rice and lemon.
अब, हम क्या चाहते हैं:
$ grep rice test_grep.txt | grep lemon
This line contains both lemon and rice.
This line also contains both rice and lemon.
हम केवल उन पंक्तियों को प्राप्त करते हैं जहां दोनों पैटर्न मेल खाते हैं। आप इसे विस्तारित कर सकते हैं और आउटपुट को दूसरे grep कमांड के लिए आगे "एंड" मैचों के लिए पाइप कर सकते हैं।
grep के साथ -P
(पर्ल-कम्पेटिबिलिटी) विकल्प और पॉजिटिव लुकहेड रेगेक्स(?=(regex))
:
grep -P '(?=.*?lemon)(?=.*?rice)' infile
या आप इसके बजाय नीचे उपयोग कर सकते हैं:
grep -P '(?=.*?rice)(?=.*?lemon)' infile
.*?
कोई भी वर्ण मिलान साधन .
घटनाओं शून्य है कि या अधिक बार *
जब वे एक पैटर्न (के बाद वैकल्पिक हैं rice
या lemon
)। इसके ?
पहले सब कुछ वैकल्पिक बनाता है (शून्य या हर चीज के मिलान का एक समय .*
)(?=pattern)
: पॉजिटिव लुकहैड: पॉजिटिव लुकहेड कंस्ट्रक्शन में कोष्ठकों की एक जोड़ी होती है, जिसमें ओपनिंग कोष्ठक के बाद एक प्रश्न चिह्न और एक बराबर चिन्ह होता है।
तो यह सभी पंक्तियों के साथ lemon
और rice
यादृच्छिक क्रम में दोनों को लौटाएगा । इसके अलावा यह |
एस और डबल grep
एस के उपयोग से बचना होगा ।
बाहरी लिंक:
उन्नत ग्रीप विषय पॉजिटिव लुकहेड - डिजाइनरों के लिए जीआरपी
यदि हम स्वीकार करते हैं कि एक उत्तर प्रदान करना जो कि grep
आधारित नहीं है, स्वीकार्य है, जैसे कि ऊपर दिए गए उत्तर के आधार पर awk
, मैं एक सरल perl
पंक्ति का प्रस्ताव करूंगा जैसे:
$ perl -ne 'print if /lemon/ and /rice/' my_text_file
खोज कुछ / सभी शब्दों के साथ मामले को अनदेखा कर सकती है /lemon/i and /rice/i
। अधिकांश यूनिक्स / लिनक्स मशीनों पर पर्ल स्थापित होने के साथ-साथ वैसे भी जागृत होता है।
यहाँ grep पाइपिंग समाधान को स्वचालित करने के लिए एक स्क्रिप्ट है:
#!/bin/bash
# Use filename if provided as environment variable, or "foo" as default
filename=${filename-foo}
grepand () {
# disable word splitting and globbing
IFS=
set -f
if [[ -n $1 ]]
then
grep -i "$1" ${filename} | filename="" grepand "${@:2}"
else
# If there are no arguments, assume last command in pipe and print everything
cat
fi
}
grepand "$@"
eval
, जो आसानी से टूट जाता है