POSIXシェルスクリプトで疑似配列を使用する方法
Bashスクリプトの10個の整数の配列を、POSIXシェルスクリプトと同様のsomethingに置き換えます。
なんとか Rich’s sh(POSIX Shell)tricks 、セクションWorking with arrayに遭遇しました。
私が試したこと:
save_pseudo_array()
{
for i do
printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"
done
echo " "
}
coords=$(save_pseudo_array "$@")
set -- 1895 955 1104 691 1131 660 1145 570 1199 381
eval "set -- $coords"
私はそれを理解していません、それが問題です、誰かがそれにいくつかの光を当てることができれば、大歓迎です。
アイデアは、後でリストまたは任意の文字列を再構築するために使用できる形式で、任意の文字列のリストをスカラー変数にエンコードすることです。
$ save_pseudo_array x "y z" $'x\ny' "a'b"
'x' \
'y z' \
'x
y' \
'a'\''b' \
$
その前にset --
を付けると、x
、y z
文字列のリストを再構築して$@
配列に格納するシェルコードが作成されます。 eval
uateする必要があります。
sed
は、各文字列を適切に引用します(最初の行の最初、最後の行の終わりに'
を追加し、すべての'
を'\''
に置き換えます)。
ただし、これは、引数ごとに1つのprintf
およびsed
コマンドを実行することを意味するため、かなり非効率的です。これは、1つのawk呼び出しだけで、より簡単な方法で実行できます。
save_pseudo_array() {
LC_ALL=C awk -v q=\' '
BEGIN{
for (i=1; i<ARGC; i++) {
gsub(q, q "\\" q q, ARGV[i])
printf "%s ", q ARGV[i] q
}
print ""
}' "$@"
}
基本的な考え方は、set
を使用して、配列からインデックス付きの値を操作するエクスペリエンスを再現することです。したがって、配列を操作したい場合は、代わりに値を指定してset
を実行します。それは
set -- 1895 955 1104 691 1131 660 1145 570 1199 381
次に、$1
、$2
、for
などを使用して、指定された値を処理します。
ただし、複数のアレイが必要な場合は、あまり役に立ちません。そこにsave
とeval
のトリックがあります: Richのsave
関数 ¹は現在の位置パラメーターを処理し、適切な引用符で文字列を出力します。これをeval
と一緒に使用して、格納された値を復元できます。したがって、あなたは走る
coords=$(save "$@")
現在機能している配列をcoords
に保存してから、新しい配列を作成し、それを処理します。coords
を再び処理する必要がある場合は、eval
を使用します。
eval "set -- $coords"
この例を理解するには、ここで2つの配列(以前に値が設定され、coords
に格納されている配列)と1895、955などを含む配列を使用していることを考慮する必要があります。スニペット自体はそれだけではそれほど意味がありません。set
行とeval
行の間で処理が行われます。後で1895、955アレイに戻る必要がある場合は、coords
を復元する前に、まずそれを保存します。
newarray=$(save "$@")
eval "set -- $coords"
こうすると、復元できます$newarray
後で。
asとして定義
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}