Bourne / POSIX benzeri mermilerin split + glob operatörü vardır ve liste bağlamında bir parametre genişletmesi ( $var, $-...), komut ikamesi ( $(...)) veya aritmetik genişletme ( $((...))) bıraktığınızda çağrılır .
Aslında, for name in ${array[@]}yerine bunu yanlışlıkla başlattınız for name in "${array[@]}". (Aslında, bu operatörü yanlışlıkla çağırmanın birçok hatanın ve güvenlik açıklarının kaynağı olduğuna dikkat etmelisiniz ).
Bu operatör $IFSözel parametreyle (hangi karakterlerin bölüneceğini söylemek için (boşluk, sekme ve yeni satırın orada özel bir işlem aldığını unutmayın)) ve parçayı -fdevre dışı bırakma ( set -f) veya etkinleştirme ( set +f) seçeneğiyle yapılandırılır glob.
Ayrıca, Sin $IFSorijinal $IFSolarak Separator için (geldiği Bourne kabuğunda ) iken, POSIX kabuklarında, karakterlerin sınırlayıcı veya sonlandırıcı$IFS olarak görülmesi gerektiğini unutmayın (bir örnek için aşağıya bakın).
Bölmek için _:
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.
Ayırıcı ve ayırıcı arasındaki farkı görmek için şunu deneyin:
string='var1_var2_'
Bu onu sadece var1ve var2sadece ayıracaktır (ekstra boş eleman yok).
Dolayısıyla, JavaScript'lere benzer hale getirmek için split()ek bir adıma ihtiyacınız olacak:
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
(boş bir bölme olacağını not $stringiçine 1 (değil 0 JavaScript sitesi gibi güvenilir) eleman split()).
Özel tedaviler sekmesini, alanı ve yeni satır alımını görmek için karşılaştırın:
IFS=' '; string=' var1 var2 '
(nereden alırsınız var1ve var2)
IFS='_'; string='_var1__var2__'
Alacağınız burada: '', var1, '', var2, ''.
Not o zshkabuk yapar değil örtülü böyle o bölünmüş + glob operatörü çağırmak içinde olmadıkça shveya kshöykünme. Orada, onu açıkça çağırmalısınız. $=stringbölünmüş parça $~stringiçin, glob kısmı için ( $=~stringher ikisi için) ve ayrıca ayırıcıyı belirtebileceğiniz bir bölme operatörü vardır:
array=(${(s:_:)string})
veya boş elemanları korumak için:
array=("${(@s:_:)string}")
Orada unutmayın siçindir bölünme değil, sınırlayan ile (aynı zamanda $IFS, bilinen bir POSIX uyumsuzluk zsh). split()Boş bir dizenin 0 (1 değil) öğesine bölünmesi JavaScript'ten farklıdır .
İle dikkate değer bir fark $IFS-splitting olmasıdır ${(s:abc:)string}üzerinde böler abcile birlikte, dize IFS=abc, bu konuda ayıracaka , bya da c.
İle zsh ve ksh93, uzay, sekme veya satır almalarını özel tedavi bunları iki katına çıkarılabilir $IFS.
Tarihi bir not olarak, Bourne kabuğu (ata veya modern POSIX kabukları) her zaman boş unsurları soydu. Ayrıca, $ @ öğesinin varsayılan olmayan değerlerle bölünmesi ve genişletilmesi ile ilgili bir dizi hata vardı.$IFS . Örneğin IFS=_; set -f; set -- $@, eşdeğer değildir IFS=_; set -f; set -- $1 $2 $3....
Normal ifadelerde bölme
Şimdi JavaScript'lere daha yakın bir şey için split() düzenli ifadelere ayrılabilen için harici yardımcı programlara güvenmeniz gerekir.
POSIX araç göğsünde, genişletilmiş düzenli ifadelere bölünebilen awkbir splitoperatör vardır (bunlar, JavaScript tarafından desteklenen Perl benzeri normal ifadelerin bir veya daha fazla alt kümesidir).
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" '[_+]+'))"
zshKabuk Perl uyumlu düzenli (onun içinde ifade desteği yerleşik vardır zsh/pcrenispeten hantal mümkün olsa da, modül), ancak bir dize bölmek için kullanıyor.
shellkullanıyorsun,bashyapabilirsinIFS='_' read -a array <<< "${string}"