如何让 sed 进行参数扩展?

如何让 sed 进行参数扩展?

当前脚本是

for r in $path/[0-9]*.tst; do

sed -i s/val1/${r%.tst}/ $path/foo.bar
sed -i s/val2/${var2}/ $path/foo.bar
sed -i s/val3/${var3}/ $path/foo.bar
sed -i s/val4/${var4}/ $path/foo.bar

cat $path/foo.bar
done

值 2-4 工作正常;但是,val1 保持不变。即使我使用 ${r} 而不是 ${r%.tst},情况也是如此。

这段代码中是否存在明显的错误?

答案1

主要问题是,当它被展开时(无论有没有点扩展),都会看到$r类似path/file.tstsed

sed s/val1/path/file/

这将导致错误,因为替换字符串中的被/解释为/sed s/pattern/replacement/

你可以通过选择任何其他字符作为 sed 的模式分隔符来解决这个问题 - 选择一些不会出现在你的文件名或路径中的字符@(当然合法的文件名字符)。因此

"s@val1@${r%.tst}@"

(我在这里使用了双引号:它们允许变量扩展,同时防止其他潜在陷阱,例如全局扩展)。


就风格(和效率)而言,我建议不是多次sed调用来编辑同一个文件 - 你可以在 GNU sed 中链接多个替换表达式,-e例如

sed -i -e "s@val1@${r%.tst}@" -e "s@val2@${var2}@" -e ...

或者利用选项-f scriptfile并使用此处的文档:

for r in "$path"/[0-9]*.tst; do

sed -i -f- "$path/foo.bar" << EOF
s@val1@${r%.tst}@
s@val2@${var2}@
s@val3@${var3}@
s@val4@${var4}@
EOF

cat "$path/foo.bar"

done

相关内容