shスクリプトでarraysを使用したい。
私の目標は、a b c
という値で配列を作成し、配列内のすべての値を出力することです。
各配列の印刷に成功しましたが、配列のすべての値を印刷できませんでした。
次の例:
arrに各値を設定:
n=1
eval arr$n=a
n=2
eval arr$n=b
n=3
eval arr$n=c
arrから各値を出力:
n=1
eval echo \$arr$n
a
n=2
eval echo \$arr$n
b
n=3
eval echo \$arr$n
c
次に、すべての値を$arr
に出力し、a b c
の代わりに取得します。
n="*"
eval echo \$arr$n
{*}*
値はa b c
にする必要があります。
sh
はarrayをサポートせず、コードは配列を作成しません。 3つの変数arr1
、arr2
、arr3
を作成しました。
ksh
のようなシェルで配列要素を初期化するには、構文array[index]=value
を使用する必要があります。配列内のすべての要素を取得するには、${array[*]}
または${array[@]}
を使用します。
試してください:
n=1
eval arr[$n]=a
n=2
eval arr[$n]=b
n=3
eval arr[$n]=c
n=1
eval echo \${arr[$n]}
n=2
eval echo \${arr[$n]}
n=3
eval echo \${arr[$n]}
n='*'
eval echo \${arr[$n]}
少し遅くなりましたが、理想的なsh
の答えがここにないので、ここで説明します。添え字が必要ない場合は、sh
が効果的does配列をサポートします。スペースで区切られた文字列としてそれらをサポートするだけです。それらの内容全体を印刷したり、「プッシュ」したり、問題なく反復したりできます。
これがサンプルコードの少しです:
NAMES=""
NAMES="${NAMES} MYNAME"
NAMES="${NAMES} YOURNAME"
NAMES="${NAMES} THEIRNAME"
echo 'One at a time...'
for NAME in ${NAMES}; do
echo ${NAME};
done
echo 'All together now!'
echo ${NAMES}
どの出力:
One at a time...
MYNAME
YOURNAME
THEIRNAME
All together now!
MYNAME YOURNAME THEIRNAME
今、私はそれがサブスクリプトをサポートしていないと言いました、しかし少しのcut
マジックとスペースを適切なデリミタとして使用して、あなたは絶対にそれをエミュレートすることができます。これを上記の例の一番下に追加すると:
echo 'Get the second one'
echo ${NAMES} | cut -d' ' -f2
echo 'Add one more...'
NAMES="${NAMES} TOM"
echo 'Grab the third one'
echo ${NAMES} | cut -d' ' -f3
それを実行すると、次のようになります。
Get the second one
YOURNAME
Add one more...
Grab the third one
THEIRNAME
これは私たちが期待することです!
ただし、スペースを含む文字列は問題を引き起こす可能性があり、サブスクリプトを完全に壊します。
したがって、本当により良いステートメントは次のとおりです。配列はsh
では自明ではなく、スペースを含む文字列の配列の処理は困難です。それを行う必要がない場合(たとえば、デプロイ先のホスト名の配列)でも、sh
はこのジョブに最適なツールです。
正解は別のアプローチを見つけることであることに同意します。より良いシェルを入手するか、他のスクリプト言語(Perlやpythonなど)に切り替えるか、設計を再考してください。ただし、名前がarr
で始まるすべての変数の値のリストを取得するには、次を使用できます。
set | sed -n '/^arr[^=]*=/s///p'
これはそれらを別々の行にリストします。それらすべてを1行で取得するには、
echo $(set | sed -n '/^arr[^=]*=/s///p')
これは辞書順にソートするわけではないので、arr10
…arr19
はarr1
とarr2
の間に表示されます。 (maih1
、maih2
、…、maih10
、…、maih19
という名前のファイルがある場合も同じことが起こります。)あらかじめ配列要素の数がわかっている場合これを行うには、先行ゼロを使用してこれを修正できます。例:arr01
。 arr02
、…、99
までご案内します。
追伸変数の値のいずれかに改行が含まれている場合、set | sed …
を使用したトリックは失敗します。