在 ksh 中使用 sed 创建变量

在 ksh 中使用 sed 创建变量

我在 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。命令扩展的结果不受 shell 语法处理的影响。当您在双引号之外使用这种方式时,它仅受字段拆分(拆分为单词)文件名生成(即通配符)的影响。

在任何 shell 中,如果一个变量的名称存在于另一个变量中,则可以使用 获取该变量的值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,它告诉 shell 变量的值本身就是一个变量名,并且$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

相关内容