सादे बैश में रेगेक्सप का उपयोग करके एस्ट्रिंजेंट निकालें


97

मैं बैश का उपयोग करके एक स्ट्रिंग से समय निकालने की कोशिश कर रहा हूं, और मुझे इसका पता लगाने में मुश्किल समय आ रहा है।

मेरा तार इस तरह है:

US/Central - 10:26 PM (CST)

और मैं 10:26हिस्सा निकालना चाहता हूं ।

किसी को भी केवल बैश के साथ ऐसा करने का एक तरीका पता है - बिना sed, awk, आदि के उपयोग के?

जैसे, PHP में मैं उपयोग करूँगा - सबसे अच्छा तरीका नहीं, लेकिन यह काम करता है - कुछ इस तरह:

preg_match( ""(\d{2}\:\d{2}) PM \(CST\)"", "US/Central - 10:26 PM (CST)", $matches );

किसी भी मदद के लिए धन्यवाद, भले ही जवाब sed या awk का उपयोग करता है

जवाबों:


207

शुद्ध का उपयोग करना :

$ cat file.txt
US/Central - 10:26 PM (CST)
$ while read a b time x; do [[ $b == - ]] && echo $time; done < file.txt

बैश regex के साथ एक और समाधान:

$ [[ "US/Central - 10:26 PM (CST)" =~ -[[:space:]]*([0-9]{2}:[0-9]{2}) ]] &&
    echo ${BASH_REMATCH[1]}

एक और उपाय का उपयोग कर grepऔर उन्नत regex के आसपास देखो:

$ echo "US/Central - 10:26 PM (CST)" | grep -oP "\-\s+\K\d{2}:\d{2}"

sed का उपयोग कर एक और समाधान:

$ echo "US/Central - 10:26 PM (CST)" |
    sed 's/.*\- *\([0-9]\{2\}:[0-9]\{2\}\).*/\1/'

पर्ल का उपयोग कर एक और समाधान:

$ echo "US/Central - 10:26 PM (CST)" |
    perl -lne 'print $& if /\-\s+\K\d{2}:\d{2}/'

और पिछले एक का उपयोग कर awk:

$ echo "US/Central - 10:26 PM (CST)" |
    awk '{for (i=0; i<=NF; i++){if ($i == "-"){print $(i+1);exit}}}'

ठंडा! किसी भी मौका मैं भी पैटर्न में "-" हाइफ़न का उपयोग करें? क्योंकि उस grep ने कुछ मैच लौटाए हैं, और मुझे केवल उसी में दिलचस्पी है जिसमें हाइफ़न है और फिर एक स्थान है और फिर समय .....
andrux

मैं शायद पर्ल समाधान मिल सकता है, लेकिन यह एक उत्कृष्ट प्लस है। धन्यवाद!
andrux

मस्ती के लिए एक जोड़ा जोड़ा =)
गिलेस कोटेनोट

1
धन्यवाद के लिए मुझे \ "चाल" पता है। पर्ल सिंटैक्स के साथ grep वास्तव में शक्तिशाली है।
मार्को सुल्ला

1
मैं sedसंस्करण पसंद करता हूं, लेकिन दूसरों को चेतावनी देना चाहता था जो sedजरूरी रूप से +संशोधक नहीं लेते हैं। चारों ओर काम करने का एक तरीका {1, }एक या अधिक से मिलान करने के लिए संशोधक का उपयोग करना है।
कोडब्रिज

89
    echo "US/Central - 10:26 PM (CST)" | sed -n "s/^.*-\s*\(\S*\).*$/\1/p"

-n      suppress printing
s       substitute
^.*     anything at the beginning
-       up until the dash
\s*     any space characters (any whitespace character)
\(      start capture group
\S*     any non-space characters
\)      end capture group
.*$     anything at the end
\1      substitute 1st capture group for everything on line
p       print it

8
मुझे ऐसा लगता है कि इसने मुझे तुरंत सेड मास्टर बना दिया। एक अच्छा विकल्प जो मैं ट्वीक कर सकता हूं वह नौ से बेहतर है जो मुझे समझ नहीं आया।
नूमेनन

विस्तृत विवरण के लिए धन्यवाद, भविष्य से बचने में मदद करता है "मैं एक्सएक्सएक्स एक्सएक्सएक्सएक्स कैसे पुन: पोस्ट करता हूं"।
स्टूजेक

4
क्या आप बता सकते हैं कि आप पहले प्रिंटिंग को -nफिर से क्यों दबाते हैं /p? क्या -nध्वज को छोड़ना और /pनिर्देश को छोड़ना समान नहीं होगा ? धन्यवाद।
विक्टर ज़मानियन

बहुत बढ़िया जवाब ! आपकी मदद के लिए धन्यवाद :-)
ब्रूनो लैविट

1
@VictorZamanian यहां से : "डिफ़ॉल्ट रूप से, प्रत्येक पंक्ति में sed प्रिंट करता है। यदि यह एक प्रतिस्थापन करता है, तो नया पाठ पुराने के बजाय मुद्रित होता है। यदि आप sed के लिए एक वैकल्पिक तर्क का उपयोग करते हैं, तो" sed -n, "यह नहीं होगा। डिफ़ॉल्ट रूप से, किसी भी नई लाइनों को प्रिंट करें। ... जब "-n" विकल्प का उपयोग किया जाता है, तो "पी" ध्वज संशोधित प्रिंट का कारण होगा। "
tdashroy

26

क्विक 'एन गंदा, रेगेक्स-फ्री, कम-मजबूती-चॉप-चॉप तकनीक

string="US/Central - 10:26 PM (CST)"
etime="${string% [AP]M*}"
etime="${etime#* - }"

5
यह इतना घृणित रूप से गंदा है कि मुझे शर्म आती है कि मैंने खुद इसके बारे में नहीं सोचा। +1 | read zone dash time apm zoneकाम भी करता है
ऑरवेलोफाइल

बहुत साफ है, और बाहरी कार्यक्रमों के लिए कॉल से बचा जाता है।
विक्टर ज़मानियन

8
नमस्ते, यह 10 गुना अधिक उपयोगी होगा यदि इसमें आगे के प्रलेखन या तकनीक के आसपास के कुछ नामों का संदर्भ शामिल हो, ताकि लोग दूर जाकर अनुसंधान कर सकें। रुचि के लिए, यह बैश स्ट्रिंग हेरफेर है, और आप यहां अधिक विवरण पा सकते हैं: tldp.org/LDP/abs/html/string-manipulation.html
पेड्रो माता-मौरस

0

अगर आपका तार है

foo="US/Central - 10:26 PM (CST)"

फिर

echo "${foo}" | cut -d ' ' -f3

नौकरी करेंगे।


1
या cut -c14-18केवल जब तक चरित्र की स्थिति नहीं बदल रही है। अगर समयक्षेत्र तय हो तो ऐसा नहीं होना चाहिए।
मार्कस

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