当前脚本是
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.tst
sed
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