使用Shell脚本读取和替换键值属性

使用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

我想用相应的值替换模板文件(使用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_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[…..如果你的问题是如何通过管道编辑文件,那么关于这一点,已经有很多问题和答案了。(缩写:写入临时文件并重命名,或者使用
海绵
from
moreutils
)@CharlesDuffy,@PSkocik:为了简单起见,我将该文件复制到了一个临时文件中,但现在我面临着一个不同的问题。请参见上面的编辑。编辑一个问题,使先前的答案无效在这里是不可取的。也就是说,在PSkocik回答之前,这将是一个很好的编辑;现在,没有那么多。顺便说一句,
envsubst$file
是绝对正确的但这是错误的做法——你用重定向写入的文件会从一开始就被截断和重写,而移动操作是原子操作。此外,还缺少引用……感谢你提供了最全面的答案,也是最佳实践!感谢你提供了最全面的答案,也是最佳实践!