दो विशिष्ट वर्णों या तारों के बीच पाठ खोजना


17

कहो कि मेरे पास इस तरह की लाइनें हैं:

*[234]*
*[23]*
*[1453]*

जहां *किसी भी स्ट्रिंग (फार्म की एक स्ट्रिंग को छोड़कर [number]) का प्रतिनिधित्व करता है । मैं कमांड लाइन उपयोगिता के साथ इन पंक्तियों को कैसे पार्स कर सकता हूं और कोष्ठक के बीच की संख्या निकाल सकता हूं?

आम तौर पर, इन उपकरणों के जो cut, sed, grepया awkइस तरह के कार्य के लिए उचित होगा?

जवाबों:


16

यदि आपके पास जीएनयू जीआरईपी है, तो आप -oरेगेक्स की खोज करने के लिए इसके विकल्प का उपयोग कर सकते हैं और केवल मिलान वाले भाग को आउटपुट कर सकते हैं । (अन्य grep कार्यान्वयन केवल पूरी लाइन दिखा सकते हैं।) यदि एक पंक्ति में कई मैच हैं, तो वे अलग-अलग लाइनों पर मुद्रित होते हैं।

grep -o '\[[0-9]*\]'

यदि आप केवल अंक चाहते हैं और कोष्ठक नहीं, तो यह थोड़ा कठिन है; आपको शून्य-चौड़ाई के दावे का उपयोग करने की आवश्यकता है: एक regexp जो खाली स्ट्रिंग से मेल खाता है, लेकिन केवल अगर यह पूर्ववर्ती है, या जैसा कि मामला हो सकता है, एक ब्रैकेट द्वारा अनुसरण किया जाता है। शून्य-चौड़ाई के दावे केवल पर्ल सिंटैक्स में उपलब्ध हैं।

grep -P -o '(?<=\[)[0-9]*(?=\])'

सीड के साथ, आपको प्रिंटिंग को बंद करना होगा -n, और पूरी लाइन से मिलान करना होगा और केवल मिलान वाले भाग को बनाए रखना होगा। यदि एक पंक्ति में कई संभावित मैच होते हैं, तो केवल अंतिम मैच मुद्रित होता है। यहाँ पर sed का उपयोग करने के बारे में अधिक जानकारी के लिए आसपास के वर्णों को प्रिंट किए बिना 'sed' के साथ मिलान किए गए एक रेगेक्स को देखें ।

sed -n 's/^.*\(\[[0-9]*\]\).*/\1/p'

या यदि आप केवल अंक चाहते हैं और कोष्ठक नहीं:

sed -n 's/^.*\[\([0-9]*\)\].*/\1/p'

बिना grep -o, पर्ल यहां पसंद का उपकरण है यदि आप कुछ ऐसा चाहते हैं जो सरल और सहज दोनों है। प्रत्येक पंक्ति ( -n) पर, यदि रेखा में कोई मेल है \[[0-9]*\], तो उस मिलान ( $&) और एक नई पंक्ति ( ) को प्रिंट करें -l

perl -l -ne '/\[[0-9]*\]/ and print $&'

यदि आप केवल अंक चाहते हैं, तो समूह में परिसीमन करने के लिए कोष्ठक लगाएं, और केवल उस समूह को प्रिंट करें।

perl -l -ne '/\[([0-9]*)\]/ and print $1'

PS यदि आप केवल कोष्ठक के बीच एक या एक से अधिक अंकों की आवश्यकता चाहते हैं, तो परिवर्तन [0-9]*करें [0-9][0-9]*, या [0-9]+पर्ल में।


सभी अच्छे, इसके अलावा वह " कोष्ठक के बीच की संख्या निकालना" चाहता है । मुझे लगता है कि "को छोड़कर [number]" का मतलब है[0-9]
पीटर

1
@ पीटर। मैं समझ गया कि "[संख्या] को छोड़कर" का अर्थ है कि उस रूप की रेखा के अन्य भाग नहीं हैं। लेकिन मैंने अपने उत्तर को यह दिखाने के लिए संपादित किया कि केवल अंकों को कैसे प्रिंट किया जाए, केवल मामले में।
गिल्स एसओ- बुराई को रोकें '

1
उन perlregex मुखर वास्तव में उपयोगी लग रहे हो! मैं उनके बारे में पढ़ रहा हूं, यह देखने के बाद कि आप grep में भी पिछड़े और आगे दोनों मुखर का उपयोग करते हैं, (मैं इस तथ्य से अलग हो गया हूं कि आप एक रेगेक्स इंजन चुन सकते हैं)। मैं यहाँ से perl के regex के लिए थोड़ा और समय समर्पित करूँगा। धन्यवाद ... PS .. मैं अभी पढ़ता हूं man grep... "यह अत्यधिक प्रायोगिक है और grep -P अनिमित सुविधाओं के बारे में चेतावनी दे सकता है।" ... मुझे आशा है कि इसका मतलब अस्थिर नहीं है (?) ...
पीटर

5

आप इसके साथ नहीं कर सकते cut

  1. tr -c -d '0123456789\012'
  2. sed 's/[^0-9]*//g'
  3. awk -F'[^0-9]+' '{ print $1$2$3 }'
  4. grep -o -E '[0-9]+'

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


^.*लालच के लिए, लालची है और सभी लेकिन अंतिम अंक का उपभोग करता है, और इसके लिए पॉज़िक्स का उपयोग +करने की आवश्यकता है \+या नहीं \([0-9][0-9]*\).... और किसी भी मामले में 's/[^0-9]*//g'ठीक वैसे ही काम करता है, ... Thanks for the tr -c` उदाहरण है, लेकिन क्या यह बेहतर प्रदर्शन नहीं है \012?
पीटर

@Peter उसे पकड़ने के लिए धन्यवाद। मैंने शपथ ली होगी मैंने सेड उदाहरण का परीक्षण किया है। :( मैं अपने संस्करण के लिए यह बदल दिया है के बारे में। \012: यह अन्यथा की जरूरत है trनई-पंक्तियों खाएंगे।
केली जोन्स

अहा ... मैं इसे के रूप में देख रहा था \0, 1, 2(या यहां तक कि \, 0, 1, 2)। मैं अच्छी तरह से अष्टक के लिए पर्याप्त नहीं लगता हूं .. धन्यवाद।
पीटर

4

यदि आपका मतलब गैर-अंकों वाले अक्षरों के बीच लगातार अंकों का एक समूह निकालने में है, तो मुझे लगता है sedऔर awkये सबसे अच्छे हैं (हालाँकि grepयह आपको मिलान किए गए पात्रों को देने में सक्षम है):

sed: आप निश्चित रूप से अंकों से मेल खा सकते हैं, लेकिन यह विपरीत करने के लिए शायद दिलचस्प है, गैर-अंकों को हटा दें (जहां तक ​​प्रति पंक्ति केवल एक संख्या है):

$ echo nn3334nn | sed -e 's/[^[[:digit:]]]*//g'
3344

grep: आप लगातार अंकों का मिलान कर सकते हैं

$ echo nn3334nn | grep -o '[[:digit:]]*'
3344

मैं इसके लिए एक उदाहरण नहीं देता awkक्योंकि मुझे इसके साथ अशक्त अनुभव है; यह ध्यान रखना दिलचस्प है कि, हालांकि sedएक चाकू चाकू है, grepआपको यह करने के लिए एक सरल, अधिक पठनीय तरीका है, जो प्रत्येक इनपुट लाइन पर एक से अधिक संख्या के लिए भी काम करता है ( -oकेवल इनपुट के मिलान भागों को प्रिंट करता है, हर एक अपनी ही लाइन पर):

$ echo dna42dna54dna | grep -o '[[:digit:]]*'
42
54

एक तुलना के रूप में, यहां "प्रति पंक्ति एक से अधिक संख्या" उदाहरण का एक sedeqivalent है । । । ... (+1)grep -o '[[:digit:]]*'sed -nr '/[0-9]/{ s/^[^[0-9]*|[^0-9]*$//g; s/[^0-9]+/\n/g; p}'
पीटर।

2

चूंकि यह कहा गया है कि ऐसा नहीं किया जा सकता है cut, इसलिए मैं यह दिखाऊंगा कि किसी ऐसे समाधान का निर्माण आसानी से संभव है, जो कम से कम कुछ अन्य लोगों से भी बदतर न हो, फिर भी मैं cut"सर्वश्रेष्ठ" के रूप में उपयोग का समर्थन नहीं करता। (या एक विशेष रूप से अच्छा) समाधान। यह कहा जाना चाहिए कि कोई भी समाधान विशेष रूप से अंकों के लिए *[और ]*उसके आस - पास नहीं दिख रहा है और मान्यताओं को सरल बनाता है और इसलिए उदाहरणार्थक द्वारा दिए गए एक से अधिक जटिल उदाहरणों में असफलता का खतरा होता है (उदाहरण के बाहर *[और ]*, जिसे दिखाया नहीं जाना चाहिए)। यह समाधान कम से कम कोष्ठक की जांच करता है, और इसे तारांकन के रूप में अच्छी तरह से जांचने के लिए बढ़ाया जा सकता है (पाठक के लिए एक अभ्यास के रूप में छोड़ दिया गया):

cut -f 2 -d '[' myfile.txt | cut -f 1 -d ']'

यह -dविकल्प का उपयोग करता है, जो एक सीमांकक निर्दिष्ट करता है। जाहिर है आप cutएक फ़ाइल से पढ़ने के बजाय अभिव्यक्ति में भी पाइप कर सकते हैं । हालांकि cutयह बहुत तेज़ है, क्योंकि यह सरल है (कोई रेगेक्स इंजन नहीं है), आपको इसे कम से कम दो बार (या कुछ और समय की जाँच करने के लिए *) आह्वान करना होगा , जिससे कुछ प्रक्रिया ओवरहेड हो जाती है। इस समाधान का एक वास्तविक लाभ यह है कि यह पठनीय है, विशेष रूप से आकस्मिक उपयोगकर्ताओं के लिए अच्छी तरह से regex निर्माण में निपुण नहीं है।

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