我正在尝试编写一个脚本,该脚本在特定模式 ( {?varname}
)中查找字符串并用相应的环境变量替换它们。
这是我到目前为止:
function get_env() {
var=$1
echo ${!var}
}
sed -e 's/{?\([a-z]*}\)/'$(get_env '\1')'/g' file.txt
Run Code Online (Sandbox Code Playgroud)
该功能有效,例如get_env LOGNAME
-->dotan
sed 返回函数的值,例如,如果我将函数的内容替换为echo __$1__
I will get {?logname}
-->__LOGNAME__
然而放在一起是行不通的。这就像函数总是返回一个空字符串。
我不确定是什么导致了这里的问题。有任何想法吗?
该命令行将get_env '\1'
在命令替换中运行,并将其输出粘贴到sed
. 您可能应该收到一个错误消息,因为\1
它不是变量的有效名称。
你可以使用 Perls/\{\?([a-z]+)\}/$ENV{$1}/
来做到这一点;%ENV
是一个包含环境变量的哈希:
$ export name=you
$ echo "hello {?name}" | perl -pe 's/\{\?([a-z]+)\}/$ENV{$1}/'
hello you
Run Code Online (Sandbox Code Playgroud)
(GNU sed 有e
运行外部程序的命令,但它使用运行整个模式空间,而不仅仅是匹配部分,所以它似乎不太适合这里。)
纯粹在 Bash 中,如果您坚持 ( setvar.sh
):
#!/bin/bash
while IFS= read -r line ; do
while [[ $line =~ ^(.*)(\{\?[a-zA-Z0-9_]+\})(.*)$ ]] ; do
varname=${BASH_REMATCH[2]}
varname=${varname#"{?"}
varname=${varname%\}}
printf -v line "%s%s%s" "${BASH_REMATCH[1]}" "${!varname}" "${BASH_REMATCH[3]}"
done
printf "%s\n" "$line"
done < "${1-/dev/stdin}"
$ echo 'foo {?BASH_VERSION} {?blah} bar' |blah=ABC bash setvar.sh
foo 4.4.12(1)-release ABC bar
Run Code Online (Sandbox Code Playgroud)