जवाबों:
इसे काम करने की कुंजी यह बताना sed
है कि आप जो उत्पादन नहीं करना चाहते हैं उसे बाहर करने के साथ-साथ यह भी निर्दिष्ट करें कि आप क्या चाहते हैं।
string='This is a sample 123 text and some 987 numbers'
echo "$string" | sed -rn 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+([[:digit:]]+)[^[:digit:]]*/\1 \2/p'
यह कहता है:
-n
)p
)सामान्य तौर पर, sed
आप कोष्ठक और आउटपुट का उपयोग करके समूहों को कैप्चर करते हैं जो आप एक बैक रेफरेंस का उपयोग करके कैप्चर करते हैं:
echo "foobarbaz" | sed 's/^foo\(.*\)baz$/\1/'
"बार" का उत्पादन करेगा। यदि आप विस्तारित रेगेक्स के लिए -r
( -E
ओएस एक्स के लिए) उपयोग करते हैं, तो आपको कोष्ठक से बचने की आवश्यकता नहीं है:
echo "foobarbaz" | sed -r 's/^foo(.*)baz$/\1/'
इसमें 9 कैप्चर ग्रुप और उनके बैक रेफरेंस हो सकते हैं। समूहों को दिखाई देने वाले क्रम में पीछे संदर्भ दिए गए हैं, लेकिन उनका उपयोग किसी भी क्रम में किया जा सकता है और दोहराया जा सकता है:
echo "foobarbaz" | sed -r 's/^foo(.*)b(.)z$/\2 \1 \2/'
आउटपुट "एक बार"।
यदि आपके पास GNU है grep
(यह OS X सहित BSD में भी काम कर सकता है):
echo "$string" | grep -Po '\d+'
या विविधताएँ जैसे:
echo "$string" | grep -Po '(?<=\D )(\d+)'
-P
विकल्प पर्ल कम्पैटिबल रेग्युलर एक्सप्रेशंस सक्षम बनाता है। देखें man 3 pcrepattern
या man
3 pcresyntax
।
sed
उदाहरण का उल्लेख कर रहे हैं , यदि आप -r
विकल्प का उपयोग करते हैं (या -E
OS X, IIRC के लिए) तो आपको कोष्ठक से बचने की आवश्यकता नहीं है। अंतर यह है कि बुनियादी नियमित अभिव्यक्तियों और विस्तारित नियमित अभिव्यक्तियों ( -r
) के बीच।
सैड में नौ याद किए गए पैटर्न होते हैं, लेकिन आपको नियमित अभिव्यक्ति के कुछ हिस्सों को याद रखने के लिए बची हुई कोष्ठक का उपयोग करने की आवश्यकता होती है।
उदाहरण और अधिक विस्तार के लिए यहां देखें
sed -e 's/version=\(.+\)/\1/' input.txt
इस अभी भी उत्पादन पूरी input.txt
\+
इसके बजाय लिखना है +
। और मुझे समझ में नहीं आता कि लोग -e
सिर्फ एक सेड कमांड के लिए क्यों इस्तेमाल करते हैं।
sed -e -n 's/version=\(.+\)/\1/p' input.txt
देखें: mikeplate.com/2012/05/09/…
sed -E
तथाकथित "आधुनिक" या "विस्तारित" नियमित अभिव्यक्तियों का उपयोग करने का सुझाव दूंगा जो पर्ल / जावा / जावास्क्रिप्ट / गो / जो भी जायके के बहुत करीब दिखते हैं। (तुलना करें grep -E
या egrep
।) डिफ़ॉल्ट सिंटैक्स में उन अजीब भागने के नियम होते हैं और उन्हें "अप्रचलित" माना जाता है। दोनों के बीच अंतर के बारे में अधिक जानकारी के लिए, दौड़ें man 7 re_format
।
आप grep का उपयोग कर सकते हैं
grep -Eow "[0-9]+" file
o
- इसीलिए विकल्प है - unixhelp.ed.ac.uk/CGI/man-cgi?grep : -o, - केवल-मिलान केवल PATNN से मेल खाने वाली रेखा के एक हिस्से को दिखाता है
grep -Eow -e "[0-9]+" -e "[abc]{2,3}"
मुझे नहीं पता कि आपको उन दो अभिव्यक्तियों की आवश्यकता कैसे हो सकती है जो पिछले grep से पाइपिंग से अलग एक पंक्ति में हों (जो कि तब भी काम नहीं कर सकते थे जब या तो पैटर्न एक पंक्ति में एक से अधिक बार मेल खाता हो। )।
यह उत्तर अंकों के किसी भी समूह के साथ काम करता है। उदाहरण:
$ echo 'Num123that456are7899900contained0018166intext' |
> sed -En 's/[^0-9]*([0-9]{1,})[^0-9]*/\1 /gp'
123 456 7899900 0018166
वहाँ उत्पादन करने के लिए sed केवल कब्जा समूहों को बताने के लिए कोई रास्ता नहीं है?
हाँ। कैप्चर ग्रुप द्वारा सभी टेक्स्ट को बदलें:
$ echo 'Number 123 inside text' | sed 's/[^0-9]*\([0-9]\{1,\}\)[^0-9]*/\1/'
123
s/[^0-9]* # several non-digits
\([0-9]\{1,\}\) # followed by one or more digits
[^0-9]* # and followed by more non-digits.
/\1/ # gets replaced only by the digits.
या विस्तारित सिंटैक्स के साथ (कम बैकक्वाट और + के उपयोग की अनुमति दें):
$ echo 'Number 123 in text' | sed -E 's/[^0-9]*([0-9]+)[^0-9]*/\1/'
123
नंबर न होने पर मूल पाठ को प्रिंट करने से बचने के लिए:
$ echo 'Number xxx in text' | sed -En 's/[^0-9]*([0-9]+)[^0-9]*/\1/p'
और कई नंबरों का मिलान करने के लिए (और उन्हें प्रिंट भी करें):
$ echo 'N 123 in 456 text' | sed -En 's/[^0-9]*([0-9]+)[^0-9]*/\1 /gp'
123 456
अंकों की किसी भी गणना के लिए यह काम करता है:
$ str='Test Num(s) 123 456 7899900 contained as0018166df in text'
$ echo "$str" | sed -En 's/[^0-9]*([0-9]{1,})[^0-9]*/\1 /gp'
123 456 7899900 0018166
जो कि grep कमांड के समान है:
$ str='Test Num(s) 123 456 7899900 contained as0018166df in text'
$ echo "$str" | grep -Po '\d+'
123
456
7899900
0018166
और मॉडल:
/([\d]+)/
Sed '\ d' (शॉर्टकट) सिंटैक्स को नहीं पहचानता है। ऊपर उपयोग की गई एससीआई समतुल्य समकक्ष [0-9]
नहीं है। एकमात्र वैकल्पिक उपाय वर्ण वर्ग का उपयोग करना है: '[[अंक:]]] `।
चयनित उत्तर समाधान बनाने के लिए इस तरह के "चरित्र वर्गों" का उपयोग करते हैं:
$ str='This is a sample 123 text and some 987 numbers'
$ echo "$str" | sed -rn 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+([[:digit:]]+)[^[:digit:]]*/\1 \2/p'
वह समाधान केवल (ठीक) अंकों के दो रन के लिए काम करता है।
बेशक, जैसा कि उत्तर शेल के अंदर निष्पादित किया जा रहा है, हम इस तरह के उत्तर को छोटा बनाने के लिए कुछ चरों को परिभाषित कर सकते हैं:
$ str='This is a sample 123 text and some 987 numbers'
$ d=[[:digit:]] D=[^[:digit:]]
$ echo "$str" | sed -rn "s/$D*($d+)$D+($d+)$D*/\1 \2/p"
लेकिन, जैसा कि पहले ही समझाया जा चुका है, s/…/…/gp
कमांड का उपयोग करना बेहतर है:
$ str='This is 75577 a sam33ple 123 text and some 987 numbers'
$ d=[[:digit:]] D=[^[:digit:]]
$ echo "$str" | sed -rn "s/$D*($d+)$D*/\1 /gp"
75577 33 123 987
यह अंकों के दोहराए गए रनों को कवर करेगा और शॉर्ट (एर) कमांड लिखेगा।
मेरा मानना है कि प्रश्न में दिया गया पैटर्न केवल उदाहरण के माध्यम से था, और लक्ष्य किसी भी पैटर्न से मेल खाना था ।
यदि आपके पास जीएनयू एक्सटेंशन के साथ एक सीड है, जिसमें पैटर्न स्पेस में एक नई लाइन डालने की अनुमति है, तो एक सुझाव है:
> set string = "This is a sample 123 text and some 987 numbers"
>
> set pattern = "[0-9][0-9]*"
> echo $string | sed "s/$pattern/\n&\n/g" | sed -n "/$pattern/p"
123
987
> set pattern = "[a-z][a-z]*"
> echo $string | sed "s/$pattern/\n&\n/g" | sed -n "/$pattern/p"
his
is
a
sample
text
and
some
numbers
ये उदाहरण CYGWIN के साथ tcsh (हाँ, मैं इसके गलत खोल को जानता हूं ) के साथ हैं। (संपादित करें: बैश के लिए, सेट हटाएं, और रिक्त स्थान चारों ओर =)
+
, आपको इसे से बचने या -r
विकल्प ( -E
OS X के लिए) का उपयोग करने की आवश्यकता होगी । आप भी उपयोग कर सकते हैं\{1,\}
(या -r
या -E
एस्केपिंग के बिना)।
छोड़ देना और पर्ल का उपयोग करना
चूंकि sed
यह कटौती नहीं करता है, चलो बस तौलिया फेंक दें और पर्ल का उपयोग करें, कम से कम यह एलएसबी है जबकि grep
जीएनयू एक्सटेंशन नहीं हैं :-)
पूरे मिलान वाले भाग को प्रिंट करें, कोई मेल खाने वाले समूह या ज़रूरत के मुताबिक नहीं:
cat <<EOS | perl -lane 'print m/\d+/g'
a1 b2
a34 b56
EOS
आउटपुट:
12
3456
प्रति पंक्ति एकल मिलान, अक्सर संरचित डेटा फ़ील्ड:
cat <<EOS | perl -lape 's/.*?a(\d+).*/$1/g'
a1 b2
a34 b56
EOS
आउटपुट:
1
34
तलाश के साथ:
cat <<EOS | perl -lane 'print m/(?<=a)(\d+)/'
a1 b2
a34 b56
EOS
कई क्षेत्र:
cat <<EOS | perl -lape 's/.*?a(\d+).*?b(\d+).*/$1 $2/g'
a1 c0 b2 c0
a34 c0 b56 c0
EOS
आउटपुट:
1 2
34 56
प्रति पंक्ति कई मैच, अक्सर असंरचित डेटा:
cat <<EOS | perl -lape 's/.*?a(\d+)|.*/$1 /g'
a1 b2
a34 b56 a78 b90
EOS
आउटपुट:
1
34 78
तलाश के साथ:
cat EOS<< | perl -lane 'print m/(?<=a)(\d+)/g'
a1 b2
a34 b56 a78 b90
EOS
आउटपुट:
1
3478
प्रयत्न
sed -n -e "/[0-9]/s/^[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\).*$/\1 \2 \3 \4 \5 \6 \7 \8 \9/p"
मुझे यह साइबरविन के तहत मिला:
$ (echo "asdf"; \
echo "1234"; \
echo "asdf1234adsf1234asdf"; \
echo "1m2m3m4m5m6m7m8m9m0m1m2m3m4m5m6m7m8m9") | \
sed -n -e "/[0-9]/s/^[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\).*$/\1 \2 \3 \4 \5 \6 \7 \8 \9/p"
1234
1234 1234
1 2 3 4 5 6 7 8 9
$
यह वह नहीं है जो ओपी ने (समूहों को कैप्चर करने) के लिए कहा है, लेकिन आप संख्याओं का उपयोग करके निकाल सकते हैं:
S='This is a sample 123 text and some 987 numbers'
echo "$S" | sed 's/ /\n/g' | sed -r '/([0-9]+)/ !d'
निम्नलिखित देता है:
123
987
sed
साथ विस्तारित नियमित अभिव्यक्तियों को चालू करने की आवश्यकता होती है-E
।