deploy.sh
USERNAME="Tom"
PASSWORD="abc123"
FILE="config.conf"
sed -i "s/\PLACEHOLDER_USERNAME/$USERNAME/g" $FILE
sed -i "s/\PLACEHOLDER_PASSWORD/$PASSWORD/g" $FILE
config.conf
deloy="PLACEHOLDER_USERNAME"
pass="PLACEHOLDER_PASSWORD"
此文件将我在deploy中定义的变量放入我的配置文件中。我无法获取文件,所以我想以这种方式放置我的变量。
问题
我想要一个通用的命令,使用某种while循环而不是每个变量需要一个命令来为所有占位符变量工作。这意味着文件中以placeholder_开头的任何术语都将尝试替换为deploy.sh中已定义的变量的值
应设置所有变量而不是空。我想如果有能力打印警告,如果它找不到好的变量,但它不是强制性的。
答案 0 :(得分:1)
基本上,使用shell代码编写sed
脚本,然后使用sed -i .bak -f sed.script config.conf
来应用它:
trap "rm -f sed.script; exit 1" 0 1 2 3 13 15
for var in USERNAME PASSWORD
do
echo "s/PLACEHOLDER_$var/${!var}/"
done > sed.script
sed -i .bak -f sed.script config.conf
rm -f sed.script
trap 0
这里的主要“伎俩”是:
${!var}
扩展为$var
命名的变量的值,sed
将通过-f sed.script
和trap
来确保清理临时文件。您也可以使用sed -e "s/.../.../" -e "s/.../.../" -i .bak config.conf
,但我认为脚本文件更容易,特别是如果要替换的值超过2个。如果您想沿着这条路线前进,请使用bash
数组来保存sed
的参数。更仔细的脚本在脚本文件名中至少使用$$
,或使用mktemp
创建临时文件。
麻烦的是,虽然更接近通用,但它仍然不是通用的,因为我必须手动输入我想要改变的变量。是不是更像“为每个占位符_,在
deploy.sh
中找到变量并添加该变量,因此它可以适用于任意数量的变量。
因此,找到配置文件中的变量,然后应用前一个答案的技术来解决该问题:
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
for file in "$@"
do
for var in $(sed 's/.*PLACEHOLDER_\([A-Z0-9_]*\).*/\1/' "$file")
do
value="${!var}"
[ -z "$value" ] && { echo "$0: variable $var not set for $file" >&2; exit 1; }
echo "s/PLACEHOLDER_$var/$value/"
done > $tmp
sed -i .bak -f $tmp "$file"
rm -f $tmp
done
trap 0
此代码仍会从环境中提取值。如果要从shell脚本中提取设置,则需要说明所需的内容,但是可以这样做 - 脚本必须具有足够的自我意识才能找到其来源,以便可以在其中搜索名称。但基本是在这个答案;其余的是一个修修补补的问题,直到它完成你需要的东西。
答案 1 :(得分:0)
#!/bin/ksh
TemplateFile=$1
SourceData=$2
(sed 's/.*/#V0r:PLACEHOLDER_&:r0V#/' ${SourceData}; cat ${TemplateFile}) | sed -n "
s/$/²/
H
$ {
x
s/^\(\n *\)*//
# also reset t flag
t varxs
:varxs
s/^#V0r:\([a-zA-Z0-9_]\{1,\}\)=\([^²]*\):r0V#²\(\n.*\)\"\1\"/#V0r:\1=\2:r0V#²\3\2/
t varxs
# clean the line when no more occurance in text
s/^[^²]*:r0V#²\n//
# and next
t varxs
# clean the marker
s/²\(\n\)/\1/g
s/²$//
# display the result
p
}
"
这样打电话:YourScript.ksh YourTemplateFile YourDataSourceFile
其中:
deloy="PLACEHOLDER_USERNAME"
USERNAME="Tom"