私はSolaris 10システムでKsh88を使用しています。
次のようにすると:
foo="one two three"
for i in $foo; do
echo $i;
done
スクリプトは期待どおりに実行されます。
$ ./script.ksh
one
two
three
しかし、ループを次のように置き換えると:
foo="one two three"
for i in $(sed -e 's/bar/$foo/' <(echo $1));
do
echo $i
done
私はそれを実行し、これが私が得るものです:
$ ./script.ksh bar
$foo
for
コマンドの結果をsed
変数に拡張するにはどうすればよいですか?
答え1
sed -e 's/bar/$foo/' <(echo $1)
印刷$foo
。コマンド拡張の結果はシェル構文処理の影響を受けません。二重引用符の外側でこの方法を使用すると、フィールド分割(単語に分割)ファイル名の生成(ワイルドカードなど)の影響のみが受けられます。
どのシェルでも変数名が別の変数に存在する場合は、変数の値を取得できますeval
。
variable_name=$(sed -e 's/bar/foo/' <(echo $1))
case $variable_name in
*[!0-9A-Z_a-z]*) echo 1>&2 "Invalid variable name: $variable_name"; exit 3;;
esac
eval variable_value="\${$variable_name}"
for i in $variable_value; do …
$variable_value
値はスペースで区切られた部分で区切られるだけでなく、これらの部分でもワイルドカードが実行されます(たとえば、ワイルドカードはファイル名に拡張されます)。ワイルドカードをオフにするには、事前にset +f
電話してください。
ksh93では、変数を定義するときに特別なフラグを使用できますvar
。これは、変数の値自体が変数名であり、名前付き$var
変数の値に拡張する必要があることをシェルに通知することです$var
。また、foo
実際には文字列ではなく文字列のリストなので、配列を作成する必要があります。
foo=(one two three)
typeset -n variable_name="$(sed -e 's/bar/foo/' <(echo $1))"
for i in "${variable_name[@]}"; do …
答え2
foo=$(echo "$foo" | sed 's/[\\\/]/\\&/g') # only required if $foo can contain one of \/
set +f # only required if $foo contains one of \[*?
for i in $(echo "$1" | sed -e "s/bar/$foo/"); do
echo $i
done