从特定环境变量构建sed脚本

时间:2013-05-22 08:39:55

标签: bash shell sed dash-shell

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

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

$ 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脚本...: - (

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

1。主要问题

请勿使用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脚本,该脚本应根据您的需要针对模板文件运行。

答案 2 :(得分: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}"