1

我需要在 shell 中有一个非常基本的模板系统才能将 Windows 安装程序移植到 linux。所以我不能改变模板变量的语法。

我想采用特定的环境变量(以 $ENV_PREFIX 开头)并构建一个 sed 形式的脚本s/@@@${TEMPLATE_VARIABLE}@@@/$VALUE_OF_ENVIRONMENT_VARIABLE/

$TEMPLATE_VARIABLE 是去掉了 $ENV_PREFIX 的环境变量的名称。

#!/usr/bin/env sh   # no bashisms please!

TEMPLATE_FILE=$1
ENV_PREFIX="DMTMPL_"

SED_SCRIPT=""

OIFS="$IFS"
IFS=$'\012'
for VAR in "$(env | grep "^${ENV_PREFIX}")"
do
  VARIABLE=$(echo $VAR | cut -d= -f1 | cut -d_ -f2-)
  SED_SCRIPT="${SED_SCRIPT}\ns/${VARIABLE}/${???}/g"
done

echo ${SED_SCRIPT}
# invoke sed with $SED_SCRIPT on $TEMPLATE_FILE

现在我遇到了这个脚本的各种问题:

  • 我尝试这样做env --null,但无法将其与以下 grep 结合使用。
  • for 循环不会在每个循环中准确处理一个环境变量
  • 我没有设法将 $SED_SCRIPT 与换行符很好地分开
  • 当变量名存储在另一个变量中时,如何访问变量的值?这就是我需要把 ??? 在脚本中。

我以为我会为此编写一个快速的 shell 脚本,但现在我记得为什么我讨厌 shell 脚本...... :-(

这些问题似乎回答了我的部分问题:

4

3 回答 3

1

如果您只是将sed命令写入临时文件,而不是尝试将它们放在单个字符串中(尤其是用于替换的任何环境变量的值中包含空格),那么脚本会简单得多。

#!/usr/bin/env sh

TEMPLATE_FILE=$1
ENV_PREFIX="DMTMPL_"

env | grep "^$ENV_PREFIX" | while IFS="=" read -r name value; do
        printf "s/%s/%s/\n" "${name#$ENV_PREFIX}" "$value"
      done > sed-script.txt

cat sed-script.txt   # Optional
sed -f sed-script.txt "$TEMPLATE_FILE"
rm sed-script.txt
于 2013-05-22T13:03:18.357 回答
0

这是我目前(工作)的解决方案:

#!/usr/bin/env sh

set -e

TEMPLATE=$1

if [ -z "${TEMPLATE}" -o ! -f ${TEMPLATE} ]
then
  echo "Did not find template file: ${TEMPLATE}"
  exit 1
fi

ENV_PREFIX="DMTMPL_"

TEMPLATE_PREFIX="PLACEHOLDER_"

SED_SCRIPT=""

OIFS=$IFS
# see https://bugs.launchpad.net/ubuntu/+source/dash/+bug/285651
IFS='
'

for VAR in `env | grep ^${ENV_PREFIX}`
do
  VARIABLE=$(echo $VAR | cut -d= -f1 )
  TEMPLATE_VARIABLE=$(echo $VARIABLE | cut -d_ -f2- )
  VALUE=$(eval "echo \$$VARIABLE")
  SED_SCRIPT="${SED_SCRIPT} --expression=\"s|${TEMPLATE_PREFIX}${TEMPLATE_VARIABLE}|${VALUE}|g\""
done

eval "sed --in-place=.sed.orig --posix ${SED_SCRIPT} ${TEMPLATE}"
于 2013-05-22T14:54:33.233 回答
0

一、主要问题

不要乱搞 IFS。更改 IFS 将使脚本的 REST 变得无用,因为现在您必须使用 \012 来分隔关键字,而不是使用空格;

您的问题很容易解决,可以使用纯 Bourne shell 代码完成:

#!/usr/bin/env sh   # no bashisms please!
TEMPLATE_FILE=$1
ENV_PREFIX="DMTMPL_"
delim='/'
sedscript="myscript.$$.sed"
rm -f $sedscript
touch $sedscript

VARS=$(env | grep "^${ENV_PREFIX}" | sed -e 's%^${ENV_PREFIX}%%')
for v in ${VARS}; do 
     eval value='${'$v'}'
     echo s${delim}@@@${v}@@@${delim}${value}${delim}g >> $sedscript
done
cat $sedscript

# sed -f $sedscript $TEMPLATE_FILE 

此脚本将创建一个 sed 脚本,该脚本应在您认为合适的情况下针对模板文件运行。

于 2013-05-22T09:05:26.643 回答