बॉर्न / POSIX की तरह गोले एक विभाजन + ग्लोब ऑपरेटर है और यह हर बार जब आप एक पैरामीटर विस्तार छोड़ लागू है ( $var, $-...), आदेश प्रतिस्थापन ( $(...)), या गणित विस्तार ( $((...))) सूची संदर्भ में गैर उद्धृत।
वास्तव में, आपने गलती से इसे लागू कर दिया जब आपने इसके for name in ${array[@]}बजाय किया for name in "${array[@]}"। (वास्तव में, आपको उस ऑपरेटर को सावधान करना चाहिए जो गलती से उस ऑपरेटर को इस तरह आमंत्रित कर रहा है जो कई बग और सुरक्षा कमजोरियों का स्रोत है )।
यही कारण है कि ऑपरेटर के साथ कॉन्फ़िगर किया गया है $IFSविशेष पैरामीटर और (क्या हो पात्रों विभाजित (हालांकि कि अंतरिक्ष, टैब सावधान रहना है और एक विशेष उपचार वहाँ) प्राप्त न्यू लाइन को बताने के लिए) -fनिष्क्रिय करने का विकल्प ( set -f) या सक्षम ( set +f) globहिस्सा।
यह भी ध्यान रखें कि जब तक Sमें $IFSमूल रूप से किया गया था (बॉर्न शैल जहां में $IFSके लिए से आता है) SPOSIX गोले में, eparator, में पात्रों $IFSके बजाय के रूप में देखा जाना चाहिए सीमांकक या टर्मिनेटर्स (उदाहरण के लिए नीचे देखें)।
तो पर विभाजित करने के लिए _:
string='var1_var2_var3'
IFS=_ # delimit on _
set -f # disable the glob part
array=($string) # invoke the split+glob operator
for i in "${array[@]}"; do # loop over the array elements.
विभाजक और सीमांकक के बीच अंतर देखने के लिए , निम्न पर प्रयास करें:
string='var1_var2_'
वह इसे var1और var2केवल (कोई अतिरिक्त खाली तत्व नहीं) विभाजित करेगा ।
तो, इसे जावास्क्रिप्ट के समान बनाने के लिए split(), आपको एक अतिरिक्त कदम की आवश्यकता होगी:
string='var1_var2_var3'
IFS=_ # delimit on _
set -f # disable the glob part
temp=${string}_ # add an extra delimiter
array=($temp) # invoke the split+glob operator
(ध्यान दें कि यह रिक्त $stringको 1 में विभाजित करेगा ( 0 नहीं ), जावास्क्रिप्ट की तरह split())।
विशेष उपचार टैब, स्पेस और न्यूलाइन प्राप्त करने के लिए, देखें:
IFS=' '; string=' var1 var2 '
(तुम कहाँ हो ) var1और के var2साथ
IFS='_'; string='_var1__var2__'
जहां आपको मिलता है: '', var1, '', var2, ''।
ध्यान दें कि zshशेल उस स्प्लिट + ग्लोब ऑपरेटर को अंतर्निहित रूप से उस तरह से लागू नहीं करता है जब तक कि shया kshअनुकरण में नहीं। वहां, आपको इसे स्पष्ट रूप से लागू करना होगा। $=stringविभाजित भाग के $~stringलिए, ग्लोब भाग के लिए ( $=~stringदोनों के लिए), और इसमें एक विभाजन ऑपरेटर भी होता है जहाँ आप विभाजक निर्दिष्ट कर सकते हैं:
array=(${(s:_:)string})
या खाली तत्वों को संरक्षित करने के लिए:
array=("${(@s:_:)string}")
ध्यान दें कि वहाँ sके लिए है बंटवारे , नहीं परिसीमन (साथ भी $IFS, का एक ज्ञात POSIX गैर अनुरूपता zsh)। यह जावास्क्रिप्ट से अलग split()है कि एक खाली स्ट्रिंग 0 (1 नहीं) तत्व में विभाजित है।
$IFS-प्लटिंग के साथ एक उल्लेखनीय अंतर यह है कि स्ट्रिंग ${(s:abc:)string}पर विभाजन होता है abc, जबकि, इसके साथ IFS=abcविभाजित होता है a, bया c।
साथ zshऔर ksh93, विशेष उपचार अंतरिक्ष, टैब या न्यू लाइन प्राप्त है कि उन्हें में दोगुना से हटाया जा सकता $IFS।
एक ऐतिहासिक नोट के रूप में, बॉर्न शेल (पूर्वज या आधुनिक POSIX गोले) ने हमेशा खाली तत्वों को छीन लिया। इसमें गैर-डिफ़ॉल्ट मूल्यों के साथ $ @ के विभाजन और विस्तार से संबंधित कई बग भी थे $IFS। उदाहरण के लिए IFS=_; set -f; set -- $@इसके बराबर नहीं होगा IFS=_; set -f; set -- $1 $2 $3...।
Regexps पर विभाजन
अब जावास्क्रिप्ट के करीब कुछ के लिए split()जो नियमित अभिव्यक्तियों पर विभाजित हो सकता है, आपको बाहरी उपयोगिताओं पर भरोसा करना होगा।
POSIX टूल-चेस्ट में, awkएक splitऑपरेटर होता है जो विस्तारित नियमित अभिव्यक्तियों पर विभाजित हो सकता है (जो जावास्क्रिप्ट द्वारा समर्थित पर्ल-रेगुलर रेग्युलर एक्सप्रेशंस का एक उपसमुच्चय है)।
split() {
awk -v q="'" '
function quote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
BEGIN {
n = split(ARGV[1], a, ARGV[2])
for (i = 1; i <= n; i++) printf " %s", quote(a[i])
exit
}' "$@"
}
string=a__b_+c
eval "array=($(split "$string" '[_+]+'))"
zshखोल पर्ल संगत नियमित अभिव्यक्ति (अपने में के लिए समर्थन अंतर्निहित है zsh/pcre, मॉड्यूल), लेकिन यह का उपयोग कर एक स्ट्रिंग विभाजित करने के लिए संभव है, हालांकि अपेक्षाकृत बोझिल है।
shellआप क्या कर रहे हैं,bashआप कर सकते हैंIFS='_' read -a array <<< "${string}"