पूरी लाइन की जरूरत नहीं है, बस नियमित अभिव्यक्ति से मैच


16

मुझे बस एक नियमित अभिव्यक्ति से मैच प्राप्त करने की आवश्यकता है:

$ cat myfile.txt | SOMETHING_HERE "/(\w).+/"

आउटपुट को केवल वही होना चाहिए जो कोष्ठक के अंदर मेल खाता था।

मुझे नहीं लगता कि मैं grep का उपयोग कर सकता हूं क्योंकि यह पूरी रेखा से मेल खाता है।

कृपया मुझे बताएँ कि यह कैसे करना है।

जवाबों:


13

2 चीजें:

  • जैसा कि @ रोरी द्वारा कहा गया है, आपको -oविकल्प की आवश्यकता है , इसलिए केवल मैच प्रिंट किए गए हैं (पूरी लाइन के बजाय)
  • इसके अलावा, आप -Pविकल्प का उपयोग करते हैं, जिसमें पर्ल रेगुलर एक्सप्रेशंस का उपयोग किया जाता है, जिसमें उपयोगी तत्व जैसे आगे देखो(?= ) और पीछे देखो (?<= ) , वे भागों की तलाश करते हैं, लेकिन वास्तव में मैच नहीं करते हैं और उन्हें प्रिंट करते हैं।

यदि आप चाहते हैं कि परेंसिस के अंदर का केवल भाग ही मिला हो:

grep -oP '(?<=\/\()\w(?=\).+\/)' myfile.txt

अगर फ़ाइल में स्टिंग है /(a)5667/, तो grep 'a' प्रिंट करेगा, क्योंकि:

  • /(द्वारा पाया जाता है \/\(, लेकिन क्योंकि वे एक नज़र में हैं कि वे (?<= )रिपोर्ट नहीं हैं
  • aद्वारा मिलान किया जाता है \wऔर इस प्रकार मुद्रित किया जाता है (क्योंकि -o)
  • )5667/बी <पाए जाते हैं \).+\/, लेकिन क्योंकि वे एक नज़र में हैं- (?= ) वे रिपोर्ट नहीं किए गए हैं

18

में -oविकल्प का उपयोग करें grep

उदाहरण के लिए:

$ echo "foobarbaz" | grep -o 'b[aeiou]r'
bar

4
अच्छा दुःख ... क्या आपके पास कोई विचार sedहै कि ऐसा करने के लिए मैंने कितनी बार backreferences के साथ कुश्ती की ?
इन्सटी

10
Grep / egrep का ओ विकल्प केवल वही लौटाता है जो पूरी नियमित अभिव्यक्ति से मेल खाता है, न कि केवल उसी तरह () में, जैसा उसने मांगा था।
काइल ब्रान्ड

1
हालांकि, वैसे भी पता करने के लिए यह एक बहुत अच्छी बात है :-)
काइल ब्रान्ड

2
@KyleBrandt: केवल एक भाग (जैसे: दृष्टांत) का मिलान करना बाकी को आगे देखो या पीछे देखना संभव है: (? <=) और (? =)
DrYak

7
    sed -n "s/^.*\(captureThis\).*$/\1/p"

-n      don't print lines
s       substitute
^.*     matches anything before the captureThis 
\( \)   capture everything between and assign it to \1 
.*$     matches anything after the captureThis 
\1      replace everything with captureThis 
p       print it

4

यदि आप केवल वही चाहते हैं जो कोष्ठक में है, तो आपको कुछ चीज़ों की ज़रूरत होती है जो उप मिलानों (नामांकित या क्रमांकित कैप्चरिंग समूहों) को कैप्चर करने का समर्थन करता है। मुझे नहीं लगता कि grep या egrep ऐसा कर सकता है, perl और sed कर सकता है। उदाहरण के लिए, पर्ल के साथ:

अगर foo नामक फाइल में एक लाइन है जो इस प्रकार है:

/adsdds      /

और आप करते हैं:

perl -nle 'print $1 if /\/(\w).+\//' foo

पत्र वापस आ गया है। हालांकि आप जो चाहते हैं वह नहीं हो सकता है। यदि आप हमें बताते हैं कि आप क्या करना चाहते हैं, तो आपको बेहतर मदद मिल सकती है। $ 1 जो कुछ भी कोष्ठक के पहले सेट में कब्जा कर लिया गया था। $ 2 दूसरा सेट होगा आदि।


मैं सिर्फ मैच करने की कोशिश कर रहा था कि कोष्ठक में क्या है। यह एक पर्ल या एक php स्क्रिप्ट को पारित करने की तरह लगता है जवाब हो सकता है।
एलेक्स एल

4

क्योंकि आपने अपने प्रश्न को शेल के अलावा बैश के रूप में टैग किया था , grep के पास एक और समाधान है :

बैश का संस्करण 3.0 से ही अपना नियमित अभिव्यक्ति इंजन है, =~ऑपरेटर की तरह, पर्ल की तरह।

अब, निम्नलिखित कोड दिया गया है:

#!/bin/bash
DATA="test <Lane>8</Lane>"

if [[ "$DATA" =~ \<Lane\>([[:digit:]]+)\<\/Lane\> ]]; then
        echo $BASH_REMATCH
        echo ${BASH_REMATCH[1]}
fi
  • ध्यान दें कि आपको सभी एक्सटेंशन प्राप्त करने के लिए इसे bashन केवल के रूप में लागू करना होगाsh
  • $BASH_REMATCH पूरे नियमित अभिव्यक्ति द्वारा मिलान के रूप में पूरे स्ट्रिंग देगा, इसलिए <Lane>8</Lane>
  • ${BASH_REMATCH[1]} इस प्रकार केवल 1 समूह द्वारा मिलान किया गया हिस्सा देगा 8

प्रिय @DyYak, मुझे आशा है कि आप XML को regex के साथ पार्स नहीं कर रहे हैं .. :)
joonas.fi

यह और भी बुरा है। मैं XML और FASTA डेटा (जो दोनों >पूरी तरह से अलग-अलग उद्देश्यों के लिए प्रतीक का उपयोग करता है) के एक भयानक मिश्रण को पार्सिंग कर रहा हूं जैसा कि SANSparallel fast लार्जस्केल अलाइनमेंट सॉफ्टवेयर द्वारा किया गया था । बेशक दोनों प्रारूपों को बिना किसी पलायन के बीच में काट दिया जाता है। इसलिए इस पर कुछ मानक XML पुस्तकालय फेंकना असंभव है। और मैं कोड के इस बिंदु पर बैश रेगेक्स का उपयोग कर रहा हूं क्योंकि मुझे केवल कुछ डेटा निकालने की आवश्यकता है, और 2 रेजेक्स इस गड़बड़ के लिए समर्पित पार्सर लिखने की तुलना में मेरे लिए बहुत बेहतर काम करते हैं। #LifeInBioinformatics
DrYak

दूसरे शब्दों में: वहाँ एक बिंदु है जहाँ 1 एकल संख्या को निकालना पूरे एक्सएमएल टैंगो को नाचने की तुलना में एक रेगेक्स रथन के साथ करना आसान है
ड्रिक

हाहा, गच्चा! :)
joonas.fi

2

फ़ाइल को मानते हुए:

$ cat file
Text-here>xyz</more text

और आप चाहते हैं कि चरित्र >और के बीच में </, आप या तो उपयोग कर सकते हैं:

grep -oP '.*\K(?<=>)\w+(?=<\/)' file
sed -nE 's:^.*>(\w+)</.*$:\1:p' file
awk '{print(gensub("^.*>(\\w+)</.*$","\\1","g"))}' file
perl -nle 'print $1 if />(\w+)<\//' file

सभी एक स्ट्रिंग "xyz" प्रिंट करेंगे।

यदि आप इस रेखा के अंकों को पकड़ना चाहते हैं:

$ cat file
Text-<here>1234</text>-ends

grep -oP '.*\K(?<=>)[0-9]+(?=<\/)' file
sed -E 's:^.*>([0-9]+)</.*$:\1:' file
awk '{print(gensub(".*>([0-9]+)</.*","\\1","g"))}' file
perl -nle 'print $1 if />([0-9]+)<\//' file


मेरे लिए महत्वपूर्ण यह महसूस करना था कि डी के साथ काम नहीं करता है। एक कारण है कि आप [0-9] + का उपयोग करते हैं। :)
user27432

@ user27423 यह नहीं है, लेकिन POSIX चरित्र वर्ग ( दर्दनाक पढ़ने , सुखद पढ़ने ) करते हैं echo 'Text-<here>1234</text>-ends' | sed -E 's|.*>([[:digit:]]+)<.*|\1|':। कुछ मामलों में (उदाहरण के लिए [0-9]बनाम [[:digit:]]) वे मदद नहीं करते हैं, लेकिन दूसरों को लगता है कि वे ऐसा करते हैं (जैसे [ \t\n\r\f\v]बनाम [:space:])।
सैमुअल हरमर

@SamuelHarmer क्या आप स्पष्ट कर सकते हैं कि ऐसा क्या है जो आपके साथ है: यह नहीं है ?
इसहाक

@Isaac मैं \dवर्ण समूह के काम न करने के बारे में @ user27432 की टिप्पणी का जिक्र कर रहा था , और पोसिक्स कक्षाओं के लिए उनका ध्यान आकर्षित कर रहा था।
शमूएल हैमर

0

यह वही होगा जो आप अनुरोध कर रहे हैं, लेकिन मुझे नहीं लगता कि यह वही है जो आप वास्तव में चाहते हैं। मैं .*मैच से पहले कुछ भी खाने के लिए रेगेक्स के सामने रखता हूं , लेकिन यह एक लालची ऑपरेशन है, इसलिए यह केवल \wस्ट्रिंग में पारंगत चरित्र से मेल खाता है ।

ध्यान दें कि आप कोष्ठक और भागने की जरूरत है +

sed 's/.*\(\w\).\+/\1/' myfile.txt
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.