シェルにJavaScriptの「split()」のようなものがありますか?

シェルにJavaScriptの「split()」のようなものがありますか?

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

$varBourne / POSIXに似たシェルには、リストコンテキストで引用符で囲まれていない引数拡張(、$-...)、コマンド置換()、または算術拡張()があるたびに$(...)呼び出される分割+glob演算子があります。$((...))

for name in ${array[@]}実際に代わりに呼び出したときに間違って呼び出しましたfor name in "${array[@]}"。 (事実に注意すべき点はこの演算子を誤って呼び出すと、多くのバグやセキュリティの脆弱性が発生します。)。

$IFSこの演算子は、分割する文字を示す特別なパラメータ(ただし、スペース、タブ、および改行文字はここで特別に処理されます)と、そのセクションを無効にする()または有効にする)オプションで構成されて-fset -fます。set +fglob

また、Sinは$IFS元々(Bourneシェルで$IFSS区切り文字として使用されていましたが、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

$stringNullを次のように分割します。1(いいえ0)要素(例:JavaScriptのsplit())。

タブ、スペース、改行の特別な処理を表示するには、次のように比較します。

IFS=' '; string=' var1  var2  '

(合計を得るvar1ところvar2

IFS='_'; string='_var1__var2__'

'', var1, '', var2, ''.

zshシェルは、inまたはエミュレーションを除いて、このような分割+glob演算子を暗黙的に呼び出しません。そこから明示的に呼び出す必要があります。分割部分とグローバル部分(両方)には、区切り文字を指定できる分割演算子もあります。shksh$=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分割されることです。abc

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" '[_+]+'))"

シェルにはzshPerl準拠の正規表現のサポートが組み込まれていますが(zsh/pcreモジュールに)、これを使用して文字列を分割するのは比較的面倒です。

おすすめ記事