split()
文字列を配列に分割するのはJavaScriptで非常に簡単です。
シェルスクリプトはどうですか?
私がこれをしたいとしましょう:
$ script.sh var1_var2_var3
ユーザーがscript.shにこれらの文字列を提供すると、var1_var2_var3
スクリプト内で文字列を配列に変換します。
array=( var1 var2 var3 )
for name in ${array[@]}; do
# some code
done
ベストアンサー1
$var
Bourne / POSIXに似たシェルには、リストコンテキストで引用符で囲まれていない引数拡張(、$-
...)、コマンド置換()、または算術拡張()があるたびに$(...)
呼び出される分割+glob演算子があります。$((...))
for name in ${array[@]}
実際に代わりに呼び出したときに間違って呼び出しましたfor name in "${array[@]}"
。 (事実に注意すべき点はこの演算子を誤って呼び出すと、多くのバグやセキュリティの脆弱性が発生します。)。
$IFS
この演算子は、分割する文字を示す特別なパラメータ(ただし、スペース、タブ、および改行文字はここで特別に処理されます)と、そのセクションを無効にする()または有効にする)オプションで構成されて-f
いset -f
ます。set +f
glob
また、S
inは$IFS
元々(Bourneシェルで$IFS
)S区切り文字として使用されていましたが、POSIXシェルではinの文字を次の$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
これにより and にのみ分割されますvar2
(追加の空の要素はありません)。
したがって、JavaScriptと同様にするには追加の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
Nullを次のように分割します。1(いいえ0)要素(例:JavaScriptのsplit()
)。
タブ、スペース、改行の特別な処理を表示するには、次のように比較します。
IFS=' '; string=' var1 var2 '
(合計を得るvar1
ところvar2
)
IFS='_'; string='_var1__var2__'
''
, var1
, ''
, var2
, ''
.
zsh
シェルは、inまたはエミュレーションを除いて、このような分割+glob演算子を暗黙的に呼び出しません。そこから明示的に呼び出す必要があります。分割部分とグローバル部分(両方)には、区切り文字を指定できる分割演算子もあります。sh
ksh
$=string
$~string
$=~string
array=(${(s:_:)string})
または空の要素を保持します。
array=("${(@s:_:)string}")
ありますs
。分ける、いいえ定義する$IFS
(また、既知のPOSIX不適合もありますzsh
。)split()
空の文字列が1以外のゼロ要素に分割される点で、JavaScriptとは異なります。
-splittingとの注目すべき違いの1つは、$IFS
文字列${(s:abc:)string}
で分割が発生するのabc
に対し、、を使用すると、またはでIFS=abc
分割されることです。a
b
c
zsh
そして、ksh93
空白、タブ、または改行文字の特殊処理を2倍にすることで削除できます$IFS
。
歴史的に、Bourneシェル(援助または最新のPOSIXシェル)は常に空の要素を削除します。また、デフォルトではなく$ @の分割と拡張に関連する多くのバグがありました$IFS
。たとえば、とIFS=_; set -f; set -- $@
同じではありませんIFS=_; set -f; set -- $1 $2 $3...
。
正規表現に基づいて分割
正規表現に基づいて分割できるJavaScriptに近いものを取得するには、split()
外部ユーティリティに依存する必要があります。
POSIXツールボックスには分割可能な演算子がawk
あります。split
拡張正規表現(これらはJavaScriptがサポートするPerlに似た正規表現のサブセットです。)
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
Perl準拠の正規表現のサポートが組み込まれていますが(zsh/pcre
モジュールに)、これを使用して文字列を分割するのは比較的面倒です。