为什么 sed 命令可以交互工作,但在我的脚本中却不能?

为什么 sed 命令可以交互工作,但在我的脚本中却不能?

SED 命令在 Debian 下不会替换 bash,但可以在命令行中使用。

在命令行中工作:

sed -i 's|/dev/disk/by-label/SR6D4|/dev/disk/by-label/SR4D4|g' /etc/my/config.xml

在 bash 脚本中不起作用,不替换字符串:

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
echo "sed -i 's|${path_from}|${path_to}|g' $file"
sed -i 's|${path_from}|${path_to}|g' $file

为什么在 bash 中使用 sed 时不替换文件中的字符串?

答案1

Shell 变量不会在单引号中扩展。 (这有点像单引号的用途。)

sed -i "s|${path_from}|${path_to}|g" "$file"

应该工作得更好。 (我添加了双引号,$file以防您的文件名包含空格。)

答案2

如前所述,您在引用时遇到问题。但是对于文件中的字符串替换有一些意见。见下文。

替换文件中的字符串是个坏主意,因为它不安全。更改时文件数据丢失的可能性很小。

您可以尝试在更改之前备份文件:

cp /path/to/file{,.backup}
sed -i 'place your pattern here' /path/to/file

你将得到名为 的文件file.backup

您需要记住:如果您的文件被损坏并且您将删除并替换它 - 文件将具有不同的索引节点并且将丢失所有硬链接。

第二种安全方法:

mv /path/to/file{,.backup}; 
cat /path/to/file.backup | sed 'place your pattern here' > /path/to/file

下一点。作为bash常见问题解答认为:

在 sed 命令中嵌入 shell 变量从来都不是一个好主意

这就是为什么你需要使用awk选项-v。您的脚本可能如下所示:

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
sed -i 's|${path_from}|${path_to}|g' $file
mv $file{,.backup}
cat "${file}.backup" | awk -v awkfrom="$path_from" -v awkto="$path_to" '{gsub(awkfrom,awkto)}' > $file

相关内容