我试图编写一个bash脚本来replace文件中所有出现的占位符与同名的环境variables。 作为一个例子,如果我有像下面这样的文件…
This is an {{VAR1}} {{VAR2}}. It should work across multiple lines in this {{VAR2}}.
…我有以下的环境variables设置:
VAR1='example' VAR2='file'
在我的文件上运行脚本后,我应该得到的输出:
This is an example file. It should work across multiple lines in this file.
我确定使用awk / sed必须有一个解决scheme,但是到目前为止,如果一行中有多个variables,那么最近我不能处理。 这是我迄今为止的尝试:
cat example.txt | grep -o '{{.*}}' > temp while read placeholder; do varName=$(echo "$placeholder" | tr -d '{}') value="${!varName}" sed -i "s/$placeholder/$value/g" "$file" done < temp rm -rf temp
我会使用Perl:
perl -pe 's/{{(.*?)}}/$ENV{$1}/g' filename
这假设VAR1
和VAR2
是环境变量(即export
),以便Perl可以将它们从环境中挑选出来。 这将是任何不是纯粹的方法的要求, 我只是提到它以避免混淆。
这工作如下:
s/pattern/replacement/g
是替换命令; 你可以从sed中识别出来。 不同的是,在这里我们可以使用Perl的更强大的正则表达式引擎和变量。 克旗使得所有的比赛都被取代; 没有它,它只适用于第一个。 .*?
非贪婪匹配,因此在包含foo {{VAR1}} bar {{VAR2}} baz
,模式{{.*?}}
仅匹配{{VAR1}}
而不匹配{{VAR1}} bar {{VAR2}}
。 {{
和}}
之间的部分被捕获,因为它在()
之间,可以作为$1
重用 $ENV{$1}
使用包含Perl进程环境的特殊%ENV
哈希。 $ENV{$1}
是名称$1
的环境变量的值,它是之前捕获的组。 只有bash
和sed
:
$ VAR1='example' $ VAR2='file' $ export VAR1 VAR2 $ sed -e '{s/{{\([^{]*\)}}/${\1}/g; s/^/echo "/; s/$/";/}' -ee filename This is an example file. It should work across multiple lines in this file.
sed -e '{s/{{\([^{]*\)}}/${\1}/g;}' filename
:
This is an ${VAR1} ${VAR2}. It should work across multiple lines in this ${VAR2}.
{{\([^{]*\)}}
– 搜索{{..}}
[^{]
– 非贪婪的匹配 \1
– 访问括号内的值\(...\)
。 sed -e '{s/{{\([^{]*\)}}/${\1}/g; s/^/echo "/; s/$/";/}' filename
sed -e '{s/{{\([^{]*\)}}/${\1}/g; s/^/echo "/; s/$/";/}' filename
:
echo "This is an ${VAR1} ${VAR2}."; echo "It should work across multiple lines in this ${VAR2}.";
s/^/echo "/
– 用s/^/echo "/
替换行的开头echo "
s/$/";/
– 用s/$/";/
替换行的结尾";
我只是在玩你原来的方法。 $varName
工作不会添加另一个循环?
cat example.txt | grep -o '{{.*}}' > temp while read placeholder; do varName=$(echo "$placeholder" | tr -d '{}') for i in $varName; do value="${!i}" sed -i "s/{{$i}}/$value/g" example.txt done done < temp rm -rf temp