BASH 3 और इसके बाद के संस्करण में शायद सबसे आसान और सबसे सुरक्षित तरीका है:
var="string to split"
read -ra arr <<<"$var"
( arr
वह सरणी कहां है जो स्ट्रिंग के विभाजित भागों को लेती है) या, अगर इनपुट में नईलाइन हो सकती हैं और आप केवल पहली पंक्ति से अधिक चाहते हैं:
var="string to split"
read -ra arr -d '' <<<"$var"
(कृपया इसमें स्थान नोट करें -d ''
, इसे छोड़ा नहीं जा सकता है), लेकिन इससे आपको एक अनपेक्षित न्यूलाइन मिल सकती है <<<"$var"
(जैसा कि यह अंत में एक LF जोड़ता है)।
उदाहरण:
touch NOPE
var="* a *"
read -ra arr <<<"$var"
for a in "${arr[@]}"; do echo "[$a]"; done
अपेक्षित उत्पादन करता है
[*]
[a]
[*]
इस समाधान के रूप में (यहां पिछले सभी समाधानों के विपरीत) अप्रत्याशित और अक्सर बेकाबू खोल गोलाबारी होने का खतरा नहीं है।
इसके अलावा यह आपको IFS की पूरी शक्ति देता है जैसा कि आप शायद चाहते हैं:
उदाहरण:
IFS=: read -ra arr < <(grep "^$USER:" /etc/passwd)
for a in "${arr[@]}"; do echo "[$a]"; done
आउटपुट कुछ इस तरह है:
[tino]
[x]
[1000]
[1000]
[Valentin Hilbig]
[/home/tino]
[/bin/bash]
जैसा कि आप देख सकते हैं, रिक्त स्थान को इस तरह भी संरक्षित किया जा सकता है:
IFS=: read -ra arr <<<' split : this '
for a in "${arr[@]}"; do echo "[$a]"; done
आउटपुट
[ split ]
[ this ]
कृपया ध्यान दें कि IFS
BASH में हैंडलिंग अपने आप में एक विषय है, इसलिए अपने परीक्षण, इस पर कुछ दिलचस्प विषय करें:
unset IFS
: SPC, TAB, NL के रन और इग्नोर शुरू होते हैं और समाप्त होते हैं
IFS=''
: कोई भी क्षेत्र अलग नहीं है, बस सब कुछ पढ़ता है
IFS=' '
: एसपीसी के रन (और एसपीसी केवल)
कुछ अंतिम उदाहरण
var=$'\n\nthis is\n\n\na test\n\n'
IFS=$'\n' read -ra arr -d '' <<<"$var"
i=0; for a in "${arr[@]}"; do let i++; echo "$i [$a]"; done
आउटपुट
1 [this is]
2 [a test]
जबकि
unset IFS
var=$'\n\nthis is\n\n\na test\n\n'
read -ra arr -d '' <<<"$var"
i=0; for a in "${arr[@]}"; do let i++; echo "$i [$a]"; done
आउटपुट
1 [this]
2 [is]
3 [a]
4 [test]
Btw:
यदि आपको इसकी आदत नहीं $'ANSI-ESCAPED-STRING'
है, तो यह एक समय है।
यदि आप -r
(जैसे read -a arr <<<"$var"
) को शामिल नहीं करते हैं, तो रीड बैकलैश बच जाता है। इसे पाठक के लिए व्यायाम के रूप में छोड़ दिया जाता है।
दूसरे प्रश्न के लिए:
एक स्ट्रिंग में किसी चीज के लिए परीक्षण करने के लिए मैं आमतौर पर चिपक जाता हूं case
, क्योंकि यह एक ही बार में कई मामलों की जांच कर सकता है (ध्यान दें: केस केवल पहले मैच को निष्पादित करता है, यदि आपको फैलिपल case
स्टेटमेंट का उपयोग करने की आवश्यकता है), और यह आवश्यकता अक्सर होती है (वाक्य इरादा):
case "$var" in
'') empty_var;; # variable is empty
*' '*) have_space "$var";; # have SPC
*[[:space:]]*) have_whitespace "$var";; # have whitespaces like TAB
*[^-+.,A-Za-z0-9]*) have_nonalnum "$var";; # non-alphanum-chars found
*[-+.,]*) have_punctuation "$var";; # some punctuation chars found
*) default_case "$var";; # if all above does not match
esac
तो आप एसपीसी की जाँच के लिए रिटर्न मान को इस तरह सेट कर सकते हैं:
case "$var" in (*' '*) true;; (*) false;; esac
क्यों case
? क्योंकि यह आमतौर पर रेगेक्स अनुक्रमों की तुलना में थोड़ा अधिक पठनीय है, और शेल मेटाचैकर्स के लिए धन्यवाद यह 99% सभी आवश्यकताओं को अच्छी तरह से संभालता है।