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


121

मेरे पास एक स्ट्रिंग है जैसे:

/var/cpanel/users/joebloggs:DNS9=domain.com

मुझे joebloggsइस स्ट्रिंग से उपयोगकर्ता नाम ( ) निकालने और इसे एक चर में संग्रहीत करने की आवश्यकता है।

स्ट्रिंग का प्रारूप हमेशा अपवाद के साथ समान होगा joebloggsऔर domain.comइसलिए मुझे लगता है कि स्ट्रिंग का उपयोग करके दो बार विभाजित किया जा सकता है cut?

पहले विभाजन से विभाजित होता है :और हम दूसरे विभाजन फ़ंक्शन को पारित करने के लिए एक चर में पहला भाग संग्रहीत करेंगे।

दूसरा विभाजन /अंतिम शब्द ( joebloggs) को एक चर में विभाजित करेगा

मुझे पता है कि एरेपी और स्प्लिट्स का उपयोग करके यह php में कैसे किया जाता है लेकिन मैं बैश में थोड़ा सा खो गया हूं।

जवाबों:


333

joebloggsकिसी अतिरिक्त प्रक्रिया के बिना पैरामीटर विस्तार का उपयोग करके बैश में इस स्ट्रिंग से निकालने के लिए ...

MYVAR="/var/cpanel/users/joebloggs:DNS9=domain.com" 

NAME=${MYVAR%:*}  # retain the part before the colon
NAME=${NAME##*/}  # retain the part after the last slash
echo $NAME

joebloggsरास्ते में एक विशेष गहराई पर होने पर निर्भर नहीं करता है।


सारांश

संदर्भ के लिए कुछ पैरामीटर विस्तार मोड का अवलोकन ...

${MYVAR#pattern}     # delete shortest match of pattern from the beginning
${MYVAR##pattern}    # delete longest match of pattern from the beginning
${MYVAR%pattern}     # delete shortest match of pattern from the end
${MYVAR%%pattern}    # delete longest match of pattern from the end

तो #शुरू से मैच का मतलब है (एक टिप्पणी लाइन के बारे में सोचो) और %अंत से मतलब है। एक उदाहरण का अर्थ है सबसे छोटा और दो उदाहरणों का अर्थ है सबसे लंबा।

आप संख्याओं का उपयोग करके स्थिति के आधार पर सबस्ट्रिंग प्राप्त कर सकते हैं:

${MYVAR:3}   # Remove the first three chars (leaving 4..end)
${MYVAR::3}  # Return the first three characters
${MYVAR:3:5} # The next five characters after removing the first 3 (chars 4-9)

आप विशेष स्ट्रिंग्स या पैटर्न का उपयोग करके भी बदल सकते हैं:

${MYVAR/search/replace}

patternफ़ाइल-नाम मिलान के रूप में एक ही प्रारूप में है, इसलिए *(कोई भी वर्ण) आम है, अक्सर की तरह एक विशेष प्रतीक के बाद /या.

उदाहरण:

जैसे एक चर दिया

MYVAR="users/joebloggs/domain.com" 

फ़ाइल नाम छोड़ने का मार्ग निकालें (स्लैश तक सभी वर्ण):

echo ${MYVAR##*/}
domain.com

पथ को छोड़कर, फ़ाइल का नाम निकालें (अंतिम के बाद सबसे छोटा मिलान हटाएं /):

echo ${MYVAR%/*}
users/joebloggs

बस फ़ाइल एक्सटेंशन प्राप्त करें (अंतिम अवधि से पहले सभी को हटा दें):

echo ${MYVAR##*.}
com

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

NAME=${MYVAR##*/}      # remove part before last slash
echo ${NAME%.*}        # from the new var remove the part after the last period
domain

मुझे यकीन नहीं है कि अगर यह grep के रचनात्मक उपयोग के लिए या इसके खिलाफ एक तर्क है, लेकिन इसे VAR = / here / / / / पथ के साथ आज़माएं: / a / colon / अंदर: DNS9 = domain.com
rici

2
मिठाई! और इसे निष्पादित शेल के अंदर किया जाता है, जिससे अन्य कमांड्स का उपयोग करने की तुलना में तेजी से होता है।
स्टोल्कविक

3
@ फड़ी आपको वाइल्डकार्ड को कोलन से पहले आने के लिए स्विच करना है, और #इसके बजाय उपयोग करना है %। यदि आप बहुत पिछले बृहदान्त्र के बाद केवल भाग चाहते हैं, ${MYVAR##*:}तो पहले बृहदान्त्र के बाद का हिस्सा प्राप्त करने के लिए उपयोग करें, उपयोग करें${MYVAR#*:}
बेरो

4
मित्र, आप नहीं जानते कि मैं इस उत्तर पर कितनी बार आया हूं। धन्यवाद!
जोएल बी

1
बहुत बढ़िया जवाब! प्रश्न: यदि मेरा पैटर्न एक चर था, तो क्या मैं इसे इस ${RET##*$CHOP}तरह या इस तरह ${RET##*CHOP}(या किसी अन्य तरीके से) टाइप करूंगा ? संपादित करें: पूर्व होने लगता है,${RET##*$CHOP}
Ctrl S

43

एक फ़ंक्शन को इस तरह परिभाषित करें:

getUserName() {
    echo $1 | cut -d : -f 1 | xargs basename
}

और स्ट्रिंग को एक पैरामीटर के रूप में पास करें:

userName=$(getUserName "/var/cpanel/users/joebloggs:DNS9=domain.com")
echo $userName

1
इस जवाब ने मुझे यह हासिल करने में मदद की कि मैं यहां किस लिए आया हूं। कोई भी स्वीकृत जवाब नहीं है और यह एक सादगी के लिए मेरा वोट है।
हार्परविले

1
उपरोक्त कमांड में मुझे जो एकमात्र सुधार करना था, वह ':' को इस तरह हटा रहा था echo $1 | cut -d -f 1 | xargs। सरल और साफ एएनएस के लिए +1।
भूषण

20

Sed के बारे में क्या? यह एक ही कमांड में काम करेगा:

sed 's#.*/\([^:]*\).*#\1#' <<<$string
  • #बजाय regex विभाजक के लिए इस्तेमाल किया जा रहा /है क्योंकि स्ट्रिंग है /उस में।
  • .*/ पिछले बैकस्लैश तक स्ट्रिंग को पकड़ लेता है।
  • \( .. \)एक कब्जा समूह चिह्नित करता है। यह वह जगह है \([^:]*\)
    • [^:]एक कॉलन _except किसी भी चरित्र का कहना है, और *साधन शून्य या अधिक।
  • .* बाकी लाइन का मतलब है।
  • \1इसका मतलब यह है कि पहले (और केवल) कैप्चर समूह में क्या पाया गया था। यह नाम है।

यहाँ नियमित अभिव्यक्ति के साथ स्ट्रिंग का मिलान टूट रहा है:

        /var/cpanel/users/           joebloggs  :DNS9=domain.com joebloggs
sed 's#.*/                          \([^:]*\)   .*              #\1       #'

सुपर अच्छा विच्छेदन!
19


10

एक एकल का उपयोग करना:

... | awk -F '[/:]' '{print $5}'

यही है, /या तो क्षेत्र विभाजक के रूप में उपयोग करते हुए :, उपयोगकर्ता नाम हमेशा फ़ील्ड 5 में होता है।

इसे एक चर में संग्रहीत करने के लिए:

username=$(... | awk -F '[/:]' '{print $5}')

इसके साथ एक अधिक लचीला कार्यान्वयन के sedलिए उपयोगकर्ता नाम 5 की आवश्यकता नहीं है:

... | sed -e s/:.*// -e s?.*/??

यही है, सब कुछ से :और आगे से हटाएं , और फिर आखिरी तक सब कुछ हटा दें /sedशायद इससे भी तेज है awk, इसलिए यह विकल्प निश्चित रूप से बेहतर है।

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