क्या grep केवल ऐसे शब्द दिखा सकता है जो खोज पैटर्न से मेल खाते हैं?


685

क्या खोज अभिव्यक्ति से मेल खाने वाली फ़ाइलों से grep आउटपुट "शब्द" बनाने का एक तरीका है?

अगर मैं सभी उदाहरणों को ढूंढना चाहता हूं, तो कहिए, "वें" कई फाइलों में, मैं कर सकता हूं:

grep "th" *

लेकिन आउटपुट कुछ ऐसा होगा (मेरे द्वारा बोल्ड है);

कुछ-पाठ फ़ाइल: बिल्ली पर बैठ गया चटाई  
कुछ-अन्य-पाठ फ़ाइल: जल्दी भूरी लोमड़ी  
अभी तक एक और पाठ-फ़ाइल: मुझे आशा है कि यह इसे अच्छी तरह से समझाता है 

एक ही खोज का उपयोग करके, मैं इसे आउटपुट के लिए क्या चाहता हूं:

the
the
the
this
thoroughly

क्या यह grep का उपयोग करना संभव है? या उपकरणों के एक और संयोजन का उपयोग करना?


2
डान मिडवुड समाधान पूरी तरह से काम करता है और श्रेय का हकदार है।
हकीश

क्या कोई तरीका है जो लाइनों को बदले बिना उन मिलान किए गए शब्दों को प्रिंट कर सकता है। बल्कि मिलान किए गए स्ट्रिंग को एक ही पंक्ति में रहना चाहिए?
भाषाविद

जवाबों:


955

Grep -o आज़माएँ

grep -oh "\w*th\w*" *

संपादित करें: फिल की टिप्पणी से मिलान

से डॉक्स :

-h, --no-filename
    Suppress the prefixing of file names on output. This is the default
    when there is only  one  file  (or only standard input) to search.
-o, --only-matching
    Print  only  the matched (non-empty) parts of a matching line,
    with each such part on a separate output line.

9
@ user181548, grep -o विकल्प केवल GNU grep के लिए काम करता है। इसलिए यदि आप GNU grep का उपयोग नहीं कर रहे हैं, तो यह आपके लिए काम नहीं कर सकता है।
ksinkar

5
@ABB यह निर्भर करता है कि आप मिलान की गई फ़ाइल का नाम प्रदर्शित करना चाहते हैं या नहीं। मुझे यकीन नहीं है कि यह किन परिस्थितियों में होता है और प्रदर्शित नहीं होता है, लेकिन मुझे पता है कि जब मैंने कई निर्देशिकाओं में grep का उपयोग किया, तो उसने सभी मिलान की गई फ़ाइलों के लिए पूर्ण फ़ाइल पथ प्रदर्शित किया, जबकि -h के साथ यह बस प्रदर्शित हुआ बिना किसी विनिर्देशन के शब्दों का मिलान किस फ़ाइल के बारे में है। इसलिए, मूल प्रश्न का मिलान करने के लिए, मुझे लगता है कि कुछ परिस्थितियों में यह आवश्यक है।
लोकमंच

1
मुझे क्या "\w*th\w*" *मतलब है के लिए एक स्पष्टीकरण की आवश्यकता है, इसलिए मुझे लगा कि मैं पोस्ट करूंगा। \w[_ [: alnum:]] है, इसलिए यह मूल रूप से किसी भी "शब्द" से मेल खाता है जिसमें 'th' शामिल है (क्योंकि \wइसमें स्थान शामिल नहीं है)। * उद्धृत अनुभाग के बाद एक ग्लोब है जिसके लिए फाइलें (अर्थात, इस निर्देशिका में सभी फाइलों का मिलान)
jeremysprofile

1
\wआमतौर पर पोर्टेबल नहीं है grep -E; उचित पोर्टेबिलिटी के लिए, [[:alnum:]]इसके बजाय POSIX चरित्र वर्ग नाम का उपयोग करें (या [_[:alnum:]]यदि आप वास्तव में अंडरस्कोर चाहते हैं, तो या grep -Pयदि आपके प्लेटफ़ॉर्म में है तो कोशिश करें)।
त्रिकोणीय

@ABB ओपी द्वारा दिखाए गए वांछित उत्पादन को देखते हुए -hपूरी तरह से आवश्यक है कि मैं कहूं ..?
एल रोनोको

81

क्रॉस डिस्ट्रीब्यूशन सेफ आंसर (विंडोज़ मिनीजीडब्ल्यू सहित)?

grep -h "[[:alpha:]]*th[[:alpha:]]*" 'filename' | tr ' ' '\n' | grep -h "[[:alpha:]]*th[[:alpha:]]*"

अगर आपके grep के पुराने संस्करणों (जैसे कि 2.4.2) का उपयोग करना जिसमें -o विकल्प शामिल नहीं है। उपरोक्त का उपयोग करें। वरना नीचे दिए गए संस्करण को बनाए रखने के लिए सरल का उपयोग करें।

लिनक्स क्रॉस वितरण सुरक्षित उत्तर

grep -oh "[[:alpha:]]*th[[:alpha:]]*" 'filename'

सारांश में -oh, फ़ाइल की सामग्री (और इसका फ़ाइल नाम नहीं) के लिए नियमित अभिव्यक्ति मेल खाती है, ठीक उसी तरह जैसे आप vim / etc में काम करने के लिए नियमित अभिव्यक्ति की अपेक्षा कैसे करेंगे ... तब आप किस शब्द या नियमित अभिव्यक्ति की खोज करेंगे, यह ऊपर है आप! जब तक आप POSIX पर बने रहते हैं, तब तक पर्ल सिंटैक्स नहीं (नीचे देखें)

Grep के लिए मैनुअल से अधिक

-o      Print each match, but only the match, not the entire line.
-h      Never print filename headers (i.e. filenames) with output lines.
-w      The expression is searched for as a word (as if surrounded by
         `[[:<:]]' and `[[:>:]]';

मूल कारण सभी के लिए काम नहीं करता है

\wप्लेटफ़ॉर्म से प्लेटफ़ॉर्म तक भिन्नता का उपयोग , इसके विस्तारित "पर्ल" सिंटैक्स के रूप में होता है। जैसे, उन grep स्थापना जो POSIX वर्ण वर्गों के उपयोग के साथ काम करने के लिए सीमित है, [[:alpha:]]न कि इसके पर्ल के बराबर \wअधिक के लिए नियमित अभिव्यक्ति पर विकिपीडिया पृष्ठ देखें

अंत में, ऊपर POSIX उत्तर, grep के लिए प्लेटफ़ॉर्म (मूल) होने के बावजूद अधिक विश्वसनीय होगा

बिना -o विकल्प के grep के समर्थन के लिए, पहला grep प्रासंगिक लाइनों को आउटपुट करता है, tr नई लाइनों के लिए रिक्त स्थान को विभाजित करता है, अंतिम grep केवल संबंधित लाइनों के लिए फ़िल्टर करता है।

(पुनश्च: मुझे पता है कि अब तक अधिकांश प्लेटफ़ॉर्म, \ w के लिए पैच किए गए होंगे .... लेकिन हमेशा ऐसे होते हैं जो पिछड़ जाते हैं)

@AdamRosenfield उत्तर से "-o" वर्कअराउंड के लिए क्रेडिट


1
के बारे में क्या केवल GNU grep में काम कर रहा है (जैसा कि स्वीकृत उत्तर पर टिप्पणी में उल्लेख किया गया है)?
ब्रिलियनड

@Brilliand हम्म, एक लिनक्स कार्यान्वयन को खोजने में परेशानी हो रही है जो '-o' का समर्थन नहीं करता है, मैं एक काम की तलाश कर सकता हूं अगर मुझे पता है कि किस मंच के खिलाफ जांच करनी है।
पिकोक्रेटर

@ पिको -oविकल्प विंडो ग्रीप में मौजूद नहीं है जो गिट पैकेज (minGW?) के साथ स्थापित होता है: "c:\Program Files (x86)\Git\bin\grep" --version grep (GNU grep) 2.4.2
ब्रूस पीटरसन

@BrucePeterson मैंने एडम-रोज़फील्ड वर्कअराउंड उत्तर में -o के लिए जोड़ा है: मुझे यह देखने में मदद करें कि क्या विंडो गिट में tr / sed और इसका संस्करण शामिल है। तो मैं जाँच कर सकता हूँ कि क्या यह वर्कअराउंड काम करता है
PicoCreator

@ पिको: जीआईटी के लिए: GNU sed संस्करण 4.2.1, tr (GNU textutils) 2.0
ब्रूस पीटरसन

46

यह आपके विचार से अधिक सरल है। इसे इस्तेमाल करे:

egrep -wo 'th.[a-z]*' filename.txt #### (Case Sensitive)

egrep -iwo 'th.[a-z]*' filename.txt  ### (Case Insensitive)

कहाँ पे,

 egrep: Grep will work with extended regular expression.
 w    : Matches only word/words instead of substring.
 o    : Display only matched pattern instead of whole line.
 i    : If u want to ignore case sensitivity.

2
यह 4+ वर्षों से पहले के मौजूदा उत्तरों पर कुछ भी जोड़ना प्रतीत नहीं होता है।
त्रिकोणीय

3
@tripleee मैंने पाया कि मेरा दृष्टिकोण बेहतर और सरल है इसलिए मैंने यह पोस्ट किया।
अभिनंदन प्रसाद

42

आप रिक्त स्थान को newlines और फिर grep में अनुवाद कर सकते हैं, जैसे:

cat * | tr ' ' '\n' | grep th

18
बिल्ली की जरूरत नहीं tr '' '\ n' <फ़ाइल | ग्रेप वें बड़ी फ़ाइलों के लिए धीमा।
घोस्टडॉग .४

यह काम नहीं किया। आउटपुट में फ़ाइल नाम और फ़ाइल से पूरी लाइन अभी भी समाहित थी जिसमें मैच था। वैसे भी, पेशकश किए गए अन्य समाधानों में से एक ने काम किया। वैसे, इनपुट के लिए धन्यवाद।
नील बाल्डविन

@ ghostdog74: अच्छी बात है, हालांकि अगर आपके पास फ़ाइल से अधिक है, तो आपको बिल्ली का उपयोग करने की आवश्यकता होगी। @ नील बाल्डविन: क्या आप सुनिश्चित हैं कि आपने इसे सही में टाइप किया है? जब केवल एक इनपुट फ़ाइल (इस मामले में स्टड) होती है, तो grep फ़ाइल नाम नहीं छापता है।
एडम रोसेनफील्ड

@ एडम - हाँ, क्षमा करें एडम, यह एक फ़ाइल के साथ काम करता है, लेकिन एक से अधिक नहीं।
नील बाल्डविन

4
@ घोस्टडॉग74 अगर धीमा भाग है tr, तो वह grepपहले कर सकता है , इसलिए trकेवल मिलान लाइनों पर लागू किया जाएगा:grep th filename | tr ' ' '\n' | grep th
Carcamano

37

बस awk, उपकरणों के संयोजन की जरूरत नहीं है।

# awk '{for(i=1;i<=NF;i++){if($i~/^th/){print $i}}}' file
the
the
the
this
thoroughly

8
@ अगतगंगा अच्छी तरह से, यह नाम में है
Daerdemandt

11

केवल मिलान और पर्ल के लिए grep कमांड

grep -o -P 'th.*? ' filename

3
केवल मिलान किए गए समूह के प्रदर्शन के बारे में क्या?
बिश्व मिश्र

यह काम नहीं करता है; यह केवल कभी भी मिल जाएगा thक्योंकि आपने वाइल्डकार्ड के कम से कम पुनरावृत्ति का अनुरोध किया था।
ट्रिपल

@tripleee - इसमें वह समस्या नहीं होगी, क्योंकि regex के अंत में एक स्थान शामिल है। हालांकि, यह उन शब्दों को याद करेगा जिनके पास रिक्त स्थान नहीं हैं, उदाहरण के लिए लाइनों के छोर पर।
केन विलियम्स

8

मैं सिंटैक्स को याद करने के लिए awk की मेहनत से असंतुष्ट था लेकिन मुझे ऐसा करने के लिए एक उपयोगिता का उपयोग करने का विचार पसंद आया।

ऐसा लगता है कि ऐक (या ack-grep यदि आप उबंटू का उपयोग करते हैं) तो यह आसानी से कर सकते हैं:

# ack-grep -ho "\bth.*?\b" *

the
the
the
this
thoroughly

यदि आप -h ध्वज को प्राप्त करते हैं:

# ack-grep -o "\bth.*?\b" *

some-other-text-file
1:the

some-text-file
1:the
the

yet-another-text-file
1:this
thoroughly

एक बोनस के रूप में, आप --outputध्वज को अधिक जटिल खोजों के लिए ऐसा करने के लिए उपयोग कर सकते हैं, जिसमें मैंने सबसे आसान सिंटैक्स पाया है:

# echo "bug: 1, id: 5, time: 12/27/2010" > test-file
# ack-grep -ho "bug: (\d*), id: (\d*), time: (.*)" --output '$1, $2, $3' test-file

1, 5, 12/27/2010


4

"आइकन-" के साथ शुरू होने वाले सभी शब्दों को खोजने के लिए निम्नलिखित कमांड सही है। मैं यहाँ Ack का उपयोग कर रहा हूँ, जो grep के समान है, लेकिन बेहतर विकल्पों और अच्छे स्वरूपण के साथ।

ack -oh --type=html "\w*icon-\w*" | sort | uniq

3

आप pcregrep भी आज़मा सकते हैं । Grep-w में एक विकल्प भी है , लेकिन कुछ मामलों में यह अपेक्षा के अनुरूप काम नहीं करता है।

से विकिपीडिया :

cat fruitlist.txt
apple
apples
pineapple
apple-
apple-fruit
fruit-apple

grep -w apple fruitlist.txt
apple
apple-
apple-fruit
fruit-apple

3

मुझे एक समान समस्या थी, grep / pattern regex की खोज और आउटपुट के रूप में "मिलान किए गए पैटर्न"।

अंत में मैंने egrep का उपयोग किया (grep पर एक ही regex -e या -G ने मुझे egrep का समान परिणाम नहीं दिया) विकल्प के साथ -o

इसलिए, मुझे लगता है कि यह कुछ समान हो सकता है (मैं रेगेक्स मास्टर नहीं हूं):

egrep -o "the*|this{1}|thoroughly{1}" filename

बेकार {1}क्वांटिफायर को गिराया जाना चाहिए। या यदि आप सुसंगत होना चाहते हैं, t{1}h{1}e{1}आदि
ट्रिपल

क्या यह उसी लाइन से प्रिंट कर सकता है?
吴毅 吴毅

-1

आप अपने grep आउटपुट को पर्ल में इस तरह से पाइप कर सकते हैं:

grep "th" * | perl -n -e'while(/(\w*th\w*)/g) {print "$1\n"}'

9
वह सही परिणाम नहीं देगा। इसके अलावा, अगर पर्ल का उपयोग कर रहे हैं, तो grep का उपयोग करने की कोई आवश्यकता नहीं है। पर्ल में सब कुछ करो।
भूतडोग .४

त्रुटि को इंगित करने के लिए धन्यवाद, ghostdog74। मैंने इसे केवल पहले ही नहीं, लाइन के सभी शब्दों को प्रिंट करने के लिए बदल दिया है।

जैसे मैंने कहा, grep आवश्यक नहीं है। perl -n -e'ORE (/ (\ s + th \ w *) / g) {प्रिंट "$ 1 \ n"} 'फ़ाइल
ghostdog74

7
आप पर निर्भर करता है। मैं सिर्फ एक बिंदु पर प्रकाश डाल रहा हूं। यदि इसकी आवश्यकता नहीं है, तो यह मत करो। वह अतिरिक्त "|" आप एक प्रक्रिया और अधिक खर्च होंगे।
भूतडोग .४

1
पर्ल में 5.10 या बाद में: perl -nE '@a = / (regexp) / ig; "\ n", @a 'से जुड़ें
प्रोफेसर फोटॉन

-1
$ grep -w

Grep मैन पेज से अंश:

-w: केवल उन पंक्तियों का चयन करें जिनमें मिलान वाले शब्द हों जो पूरे शब्द बनाते हों। परीक्षण यह है कि मैचिंग सबस्ट्रिंग या तो लाइन की शुरुआत में होना चाहिए, या एक गैर-शब्द घटक चरित्र से पहले होना चाहिए।


1
यह अब भी मैच वाली पूरी लाइन को प्रिंट करेगा। यह वास्तविक मैच में बाधा डालता है ताकि theअब "इन" या "बैटहे" जैसे मैच न हों ।
ट्रिपलआई

-6

ripgrep

यहाँ उदाहरण का उपयोग कर रहे हैं ripgrep:

rg -o "(\w+)?th(\w+)?"

यह मिलान वाले सभी शब्दों से मेल खाएगा th

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