使用Shell脚本读取和替换键值属性
我想用相应的值替换模板文件(使用find递归查找)中的键。密钥将从属性文件加载。请参见下面的脚本: 脚本文件内容:使用Shell脚本读取和替换键值属性,shell,unix,Shell,Unix,我想用相应的值替换模板文件(使用find递归查找)中的键。密钥将从属性文件加载。请参见下面的脚本: 脚本文件内容: . /home/uname/config/appl.properties echo ${name_1} echo ${age_1} job_1="IT" echo ${job_1} for file in $(find /home/uname/config -name "*.txt"); do echo $file temp_file="/home/uname/temp_f
. /home/uname/config/appl.properties
echo ${name_1}
echo ${age_1}
job_1="IT"
echo ${job_1}
for file in $(find /home/uname/config -name "*.txt"); do
echo $file
temp_file="/home/uname/temp_file.txt"
cp -f $file $temp_file
rm $file
envsubst < $temp_file > $file
done
name_1="theBestName"
age_1="25"
My name is ${name_1}, my age is ${age_1} and my job is in ${job_1}.
template.txt内容:
. /home/uname/config/appl.properties
echo ${name_1}
echo ${age_1}
job_1="IT"
echo ${job_1}
for file in $(find /home/uname/config -name "*.txt"); do
echo $file
temp_file="/home/uname/temp_file.txt"
cp -f $file $temp_file
rm $file
envsubst < $temp_file > $file
done
name_1="theBestName"
age_1="25"
My name is ${name_1}, my age is ${age_1} and my job is in ${job_1}.
我能够加载键/值对(echo语句显示键值),但当envsubt写出模板文件时,它不会用值替换任何键。我得到的结果是:
My name is and my age is and my job is in .
$file
在envsubst
启动之前截断文件。
使用from moreutils可以绕过这个问题,或者编写自己的海绵,在写入之前捕获所有输入。
$file
在envsubt
开始之前截断文件。
使用from moreutils可以绕过这一点,或者编写自己的海绵,在将其输出之前捕获所有输入。
envsubt
,顾名思义,要求其键/值对位于环境变量中。仅仅赋值就可以创建外壳变量,而不是环境变量
以下是最佳实践替代方案的尝试:
set -a # turn on auto-export
. appl.properties
set -a # turn off auto-export
while IFS= read -r -d '' filename; do
tempfile=$(mktemp "$filename.XXXXXX")
if envsubst <"$filename" >"$tempfile"; then
mv "$tempfile" "$filename"
else
rm -f "$tempfile"
fi
done < <(find /home/uname/config -name '*.txt' -print0)
set-a#打开自动导出
. 应用属性
设置-a#关闭自动导出
而IFS=read-r-d“”文件名;做
tempfile=$(mktemp“$filename.XXXXXX”)
如果envsubs“$tempfile”;然后
mv“$tempfile”“$filename”
其他的
rm-f“$tempfile”
fi
done<envsubt
,顾名思义,要求其键/值对位于环境变量中。仅仅赋值就可以创建外壳变量,而不是环境变量
以下是最佳实践替代方案的尝试:
set -a # turn on auto-export
. appl.properties
set -a # turn off auto-export
while IFS= read -r -d '' filename; do
tempfile=$(mktemp "$filename.XXXXXX")
if envsubst <"$filename" >"$tempfile"; then
mv "$tempfile" "$filename"
else
rm -f "$tempfile"
fi
done < <(find /home/uname/config -name '*.txt' -print0)
set-a#打开自动导出
. 应用属性
设置-a#关闭自动导出
而IFS=read-r-d“”文件名;做
tempfile=$(mktemp“$filename.XXXXXX”)
如果envsubs“$tempfile”;然后
mv“$tempfile”“$filename”
其他的
rm-f“$tempfile”
fi
完成<旁白:<代码>对于$(find…
中的文件,会遇到bashPitts#1[…..,如果您的问题是如何通过现有管道编辑文件,那么关于这一点,已经有很多问题和答案了。(缩写:写入临时文件并重命名,或者使用moreutils中的海绵)@CharlesDuffy,@PSkocik:为了简单起见,我将该文件复制到了一个临时文件中,但现在我面临着一个不同的问题。请参见上面的编辑。编辑一个问题,使先前的答案无效在这里是不可取的。也就是说,在PSkocik回答之前,这将是一个很好的编辑;现在,没有那么多。顺便说一句,envsubst$file
是绝对正确的但是,这样做的方式是错误的——您使用重定向写入的文件会从一开始就被截断和重写,而移动操作是原子操作。此外,还缺少引用……除了:对于$(find…)中的文件
与bash陷阱相冲突#1[…..如果你的问题是如何通过管道编辑文件,那么关于这一点,已经有很多问题和答案了。(缩写:写入临时文件并重命名,或者使用海绵frommoreutils
)@CharlesDuffy,@PSkocik:为了简单起见,我将该文件复制到了一个临时文件中,但现在我面临着一个不同的问题。请参见上面的编辑。编辑一个问题,使先前的答案无效在这里是不可取的。也就是说,在PSkocik回答之前,这将是一个很好的编辑;现在,没有那么多。顺便说一句,envsubst$file
是绝对正确的但这是错误的做法——你用重定向写入的文件会从一开始就被截断和重写,而移动操作是原子操作。此外,还缺少引用……感谢你提供了最全面的答案,也是最佳实践!感谢你提供了最全面的答案,也是最佳实践!