展开一个 bash 变量,但不展开它包含的变量
Expand a bash variable, but not the variables it contains
我需要能够将变量扩展为它声明字符串的确切内容,而不是像通常那样 bash 在其声明中扩展其他变量。
variable=word
var="this variable contains a $variable"
echo ????
我需要一个结果为:“this variable contains a $variable
”的命令
...而不是:“this variable contains a word
”
变量声明必须保持不变,因为它需要在所有其他情况下正常展开。所以我不能在声明中使用单引号。
你可以使用单引号:
variable=word
var='this variable contains a $variable'
echo var
您所要求的实际上是不可能的,因为在双引号内,$variable
在定义 时被该变量 的内容替换。
在您打印它时,扩展早就发生了(使用 set
可以看出)。
如果您根本无法更改定义,您唯一可以尝试的方法就是还原替换:
echo ${var/"$variable"/'$variable'}
这将替换字符串文字 $variable
当前包含的 $variable
的所有匹配项,因此在您的示例中,它将替换所有匹配项 word
为 $variable
,无论是否以这种方式定义。
此外,正如 Jasper 正确指出的那样,这依赖于 $variable
在 $var
.
的定义和打印之间没有改变的事实
现在,如果您实际上可以更改定义,但只希望扩展仍然发生,则有多种选择:
定义时使用单引号,打印时eval
。
var='this variable contains a $variable'
# later
eval "echo "'"'"$var"'"' # -> this variable contains a word
echo $var # -> this variable contains a $variable
诚然,这很麻烦。
另请注意,变量扩展发生在打印时而不是定义时(实际上,只是在任何时间 eval
运行)。
使用两个不同的变量。
不用每次都写 eval "echo "'"'"$var"'"'
,您可以将其结果存储在一个变量中并使用它,对吗?
var='this variable contains a $variable'
varX="$(eval "echo "'"'"$var"'"')"
# later
echo $varX # -> this variable contains a word
echo $var # -> this variable contains a $variable
或者,当然只是复制 $var
的定义并将 '
替换为 "
... 但那很无聊。 :P
此处扩展发生在定义$varX
时。
使用数组而不是两个不同的变量。
这真的很有趣,因为对于数组 $var
等于 ${var[0]}
,所以你可以做
tmp='this variable contains a $variable'
var=("$(eval "echo "'"'"$tmp"'"')" "$tmp")
# later
echo $var # -> this variable contains a word
echo ${var[1]} # -> this variable contains a $variable
这可能与您想要的最接近,但您仍然需要更改定义。
你也可以使用 sed
variable=word
var="this variable contains a $variable"
var=$(echo "${var}" | sed "s/${variable}/${variable}/g")
我需要能够将变量扩展为它声明字符串的确切内容,而不是像通常那样 bash 在其声明中扩展其他变量。
variable=word
var="this variable contains a $variable"
echo ????
我需要一个结果为:“this variable contains a $variable
”的命令
...而不是:“this variable contains a word
”
变量声明必须保持不变,因为它需要在所有其他情况下正常展开。所以我不能在声明中使用单引号。
你可以使用单引号:
variable=word
var='this variable contains a $variable'
echo var
您所要求的实际上是不可能的,因为在双引号内,$variable
在定义 时被该变量 的内容替换。
在您打印它时,扩展早就发生了(使用 set
可以看出)。
如果您根本无法更改定义,您唯一可以尝试的方法就是还原替换:
echo ${var/"$variable"/'$variable'}
这将替换字符串文字 $variable
当前包含的 $variable
的所有匹配项,因此在您的示例中,它将替换所有匹配项 word
为 $variable
,无论是否以这种方式定义。
此外,正如 Jasper 正确指出的那样,这依赖于 $variable
在 $var
.
现在,如果您实际上可以更改定义,但只希望扩展仍然发生,则有多种选择:
定义时使用单引号,打印时
eval
。var='this variable contains a $variable' # later eval "echo "'"'"$var"'"' # -> this variable contains a word echo $var # -> this variable contains a $variable
诚然,这很麻烦。
另请注意,变量扩展发生在打印时而不是定义时(实际上,只是在任何时间eval
运行)。使用两个不同的变量。
不用每次都写
eval "echo "'"'"$var"'"'
,您可以将其结果存储在一个变量中并使用它,对吗?var='this variable contains a $variable' varX="$(eval "echo "'"'"$var"'"')" # later echo $varX # -> this variable contains a word echo $var # -> this variable contains a $variable
或者,当然只是复制
$var
的定义并将'
替换为"
... 但那很无聊。 :P此处扩展发生在定义
$varX
时。使用数组而不是两个不同的变量。
这真的很有趣,因为对于数组
$var
等于${var[0]}
,所以你可以做tmp='this variable contains a $variable' var=("$(eval "echo "'"'"$tmp"'"')" "$tmp") # later echo $var # -> this variable contains a word echo ${var[1]} # -> this variable contains a $variable
这可能与您想要的最接近,但您仍然需要更改定义。
你也可以使用 sed
variable=word
var="this variable contains a $variable"
var=$(echo "${var}" | sed "s/${variable}/${variable}/g")