Bash变量替换和字符串

时间:2015-01-07 09:57:31

标签: bash variables substitution

假设我有两个变量:

a="AAA"
b="BBB"

我从文件中读取了一个字符串。该字符串如下:

str='$a $b'

如何从第一个替换变量的字符串创建一个新字符串?

newstr="AAA BBB"

2 个答案:

答案 0 :(得分:6)

变量间接eval

好吧,由于eval evil ,我们可以尝试通过在变量名中使用间接来实现这一点。

 a="AAA"
 b="BBB"
 str='$a $b'

 newstr=()
 for cnt in $str ;do
     [ "${cnt:0:1}" == '$' ] && cnt=${cnt:1} && cnt=${!cnt}
     newstr+=($cnt)
   done
 newstr="${newstr[*]}"

 echo $newstr
 AAA BBB

另一次尝试:

var1="Hello"
var2="2015"

str='$var1 world! Happy new year $var2'

newstr=()
for cnt in $str ;do
    [ "${cnt:0:1}" == '$' ] && cnt=${cnt:1} && cnt=${!cnt}
    newstr+=($cnt)
  done
newstr="${newstr[*]}"

echo $newstr 
Hello world! Happy new year 2015

附录正如@ EtanReisner评论所指出的那样,如果你的字符串确实包含一些*或其他 glob 消耗性蜇,那么你可能有使用set -f来防止坏事:

cd /bin
var1="Hello"
var2="star"
var3="*"
str='$var1 this string contain a $var2 as $var3 *'

newstr=()
for cnt in $str ;do
     [ "${cnt:0:1}" == '$' ] && cnt=${cnt:1} && cnt=${!cnt};
     newstr+=("$cnt");
   done;
newstr="${newstr[*]}"

echo "$newstr"
Hello this string contain a star as * bash bunzip2 busybox....zmore znew

echo ${#newstr}
1239

注意:我已在"添加newstr+=("$cnt");以阻止全局扩展,但似乎需要set -f ...

newstr=()
set -f
for cnt in $str ;do
    [ "${cnt:0:1}" == '$' ] && cnt=${cnt:1} && cnt=${!cnt}
    newstr+=("$cnt")
  done
set +f
newstr="${newstr[*]}"

echo "$newstr"
Hello this string contain a star as * *

Nota 2:这远非一个完美的解决方案。对于示例,如果字符串确实包含ponctuation,则不会再次工作......示例:

str='$var1, this string contain a $var2 as $var3: *'

与前一次运行相同的变量将呈现: ' this string contain a star as *',因为${!var1,}${!var3:}不存在。

...如果$str确实包含特殊字符:

正如@godblessfq所说:

  

如果str包含换行符,我该如何进行替换并在输出中保留换行符?

所以这不是健全因为每个间接变量必须是所有特殊字符的第一个,最后一个或空格分隔!< / em>的

str=$'$var1 world!\n... 2nd line...'
var1=Hello
newstr=()
set -f
IFS=' ' read -d$'\377' -ra array <<<"$str"
for cnt in "${array[@]}";do
    [ "${cnt:0:1}" == '$' ] && cnt=${cnt:1} && cnt=${!cnt}
    newstr+=("$cnt")
  done
set +f
newstr="${newstr[*]}"

echo "$newstr"
Hello world!
... 2nd line...

<<<内联字符串添加尾随换行符时,可以写入最后echo命令:

echo "${newstr%$'\n'}"

答案 1 :(得分:2)

最简单的解决方案是使用eval

eval echo "$str"

要将其分配给变量,请使用命令替换:

replaced=$(eval echo "$str")