读取文件并用字符串替换$ {1},$ {2} ... value

时间:2013-09-06 17:43:01

标签: shell

我有一个文件template.txt,其内容如下:

param1=${1}
param2=${2}
param3=${3}

我想用scriptParams变量的元素替换$ {1},{2},$ {3} ... $ {n}字符串值。

以下代码仅替换第一行。

scrpitParams="test1,test2,test3"

cat template.txt | for param in ${scriptParams} ; do i=$((++i)) ; sed -e "s/\${$i}/$param/" ; done

结果:

param1=test1
param2=${2}
param3=${3}

预期:

param1=test1
param2=test2
param3=test3

注意:我不想保存被替换的文件,想要使用其替换值。

3 个答案:

答案 0 :(得分:1)

学习调试:

cat template.txt | for param in ${scriptParams} ; do i=$((++i)) ; echo $i - $param; done

1 - test1,test2,test3

糟糕..

scriptParams="test1 test2 test3"

cat template.txt | for param in ${scriptParams} ; do i=$((++i)) ; echo $i - $param; done

1 - test1
2 - test2
3 - test3

好的,看起来更好......

cat template.txt | for param in ${scriptParams} ; do i=$((++i)) ; sed -e "s/\${$i}/$param/" ; done
param1=test1
param2=${2}
param3=${3}

哎呀...那么问题是什么?好吧,第一个sed命令“吃掉”所有输入。你还没有构建一个管道,其中一个sed命令提供下一个...你有三个sed试图读取相同的输入。显然,第一个处理了整个输入。

好的,让我们采取不同的方法,让我们为单个sed命令创建参数(注意:""强制echo不要解释-e作为命令行开关)。

sedargs=$(for param in ${scriptParams} ; do i=$((++i)); echo "" -e "s/\${$i}/$param/"; done)
cat template.txt | sed $sedargs

param1=test1
param2=test2
param3=test3

就是这样。请注意,这并不完美,如果替换文本很复杂(例如:包含空格),则可能会出现各种问题。

让我想一想如何以更好的方式做到这一点......(好吧,我想到的显而易见的解决方案是使用shell脚本完成此任务......)

更新: 如果你想构建一个合适的管道,这里有一些解决方案:How to make a pipe loop in bash

答案 1 :(得分:1)

你可以单独使用bash来做到这一点:

#!/bin/bash
scriptParams=("test1" "test2" "test3")  ## Better store it as arrays.
while read -r line; do
    for i in in "${!scriptParams[@]}"; do  ## Indices of array scriptParams would be populated to i starting at 0.
        line=${line/"\${$((i + 1))}"/"${scriptParams[i]}"}  ## ${var/p/r} replaces patterns (p) with r in the contents of var. Here we also add 1 to the index to fit with the targets.
    done
    echo "<br>$line</br>"
done < template.txt

将其保存在脚本中并运行bash script.sh以获得如下输出:

<br>param1=test1</br>
<br>param2=test2</br>
<br>param3=test3</br>

答案 2 :(得分:1)

如果您打算使用数组,请使用实数数组。也不需要sed

$ cat template
param1=${1}
param2=${2}
param3=${3}

$ scriptParams=("test one" "test two" "test three")
$ while read -r l; do for((i=1;i<=${#scriptParams[@]};i++)); do l=${l//\$\{$i\}/${scriptParams[i-1]}}; done; echo "$l"; done < template
param1=test one
param2=test two
param3=test three