1

我有一个文件 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

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

4

3 回答 3

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命令提供下一个命令......您有三个seds 试图读取相同的输入。显然,第一个处理了整个输入。

好的,让我们采用不同的方法,让我们为单个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

于 2013-09-06T17:47:01.387 回答
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>
于 2013-09-06T18:16:23.893 回答
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
于 2013-09-06T18:20:30.433 回答