बॉर्न / 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}"