Linux 替换文件中所有出现的占位符的bash脚本
我正在尝试编写一个bash脚本,用一个同名的环境变量替换文件中所有出现的占位符。作为一个例子,如果我有一个像下面这样的文件Linux 替换文件中所有出现的占位符的bash脚本,linux,bash,awk,sed,Linux,Bash,Awk,Sed,我正在尝试编写一个bash脚本,用一个同名的环境变量替换文件中所有出现的占位符。作为一个例子,如果我有一个像下面这样的文件 This is an {{VAR1}} {{VAR2}}. It should work across multiple lines in this {{VAR2}}. 。。。我设置了以下环境变量: VAR1='example' VAR2='file' 在我的文件上运行脚本后,我应该获得输出: This is an example file. It should wor
This is an {{VAR1}} {{VAR2}}.
It should work across multiple lines in this {{VAR2}}.
。。。我设置了以下环境变量:
VAR1='example'
VAR2='file'
在我的文件上运行脚本后,我应该获得输出:
This is an example file.
It should work across multiple lines in this file.
我确信一定有一个使用awk/sed的解决方案,但到目前为止,我所遇到的最接近的解决方案无法处理一行中是否有多个变量。以下是我迄今为止的尝试:
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
cat example.txt | grep-o'{{.*}>temp
读占位符时;做
varName=$(echo“$placeholder”| tr-d'{}')
value=“${!varName}”
sed-i“s/$placeholder/$value/g”“$file”
完成<温度
rm-射频温度
我会使用Perl:
perl -pe 's/{{(.*?)}}/$ENV{$1}/g' filename
这假设VAR1
和VAR2
是环境变量(即export
ed),因此Perl可以从其环境中选择它们。这对于任何非纯shell的方法都是必需的;我只是提一下以避免混淆
这项工作如下:
是一个替换命令;您可以从sed中识别它。不同之处在于,这里我们可以使用Perl更强大的正则表达式引擎和变量。s/pattern/replacement/g
标志使其能够替换所有匹配项;如果没有它,它将只适用于第一个g
- 在模式中,
不贪婪地匹配,因此在包含*?
的行中,模式foo{{VAR1}}bar{{VAR2}baz
只匹配{.*}
,而不是{VAR1}
{VAR1}}bar{{VAR2}
- 捕获
和{{
之间的部分,因为它位于}
之间,可以作为()
重用$1
- 替换中的
使用包含Perl进程环境的特殊$ENV{$1}
哈希%ENV
是名为$ENV{$1}
的环境变量的值,它是以前捕获的组$1
bash
和sed
:
$ VAR1='example'
$ VAR2='file'
$ export VAR1 VAR2
$ sed -e '{s/{{\([^{]*\)}}/${\1}/g; s/^/echo "/; s/$/";/}' -e e filename
This is an example file.
It should work across multiple lines in this file.
:sed-e'{s/{\([^{]*\)}/${\1}/g;}'文件名
This is an ${VAR1} ${VAR2}. It should work across multiple lines in this ${VAR2}.
echo "This is an ${VAR1} ${VAR2}."; echo "It should work across multiple lines in this ${VAR2}.";
-搜索{{\([^{]*\)}
{{..}}
-非贪婪匹配[^{]
-访问括号内的值\1
\(…\)
:sed-e'{s/{\([^{]*\)}/${\1}/g;s/^/echo/;s/$/“;/}”文件名
This is an ${VAR1} ${VAR2}. It should work across multiple lines in this ${VAR2}.
echo "This is an ${VAR1} ${VAR2}."; echo "It should work across multiple lines in this ${VAR2}.";
-将行的开头替换为s/^/echo”/
echo“
-将行尾替换为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
cat example.txt | grep-o'{{.*}>temp
读占位符时;执行
varName=$(echo“$placeholder”| tr-d'{}')
因为我用$varName;做
value=“${!i}”
sed-i“s/{{$i}}/$value/g”example.txt
完成
完成<温度
rm-射频温度
你考虑过使用m4
宏处理器吗?@MarkSetchell我没听说过m4,但我会去看看。谢谢。这太棒了-正是我想要的!谢谢@Wintermute!在运行此操作之前,确保在脚本中导出VAR1 VAR2,否则它将无法工作。