Bash 脚本,字符串未用转义的 $ 和 & 字符正确替换

Bash 脚本,字符串未用转义的 $ 和 & 字符正确替换

我创建了一个 shell 脚本,它接受一个字符串作为输入。如果字符串包含$&,那么我需要用\$和替换这些字符\&。我可以用命令完成sed。之后我想用相应的字符串替换特定文本文件中的单词。

请参阅本节以了解更多说明。

这是我的文件。

test.txt

hello my root password is root.

现在,我想用字符串更改词根。字符串可以是任何内容,其中可能包括特殊字符,如$&

如果我想root用字符串替换my&rootpa$$,那么它应该看起来像my\&rootpa\$\$文本文件。

这是我的 shell 脚本

#!/bin/bash
dothis(){
    rootpass=$(echo "$1" | sed -r 's/\$/\\$/g');
    rootpass=$(echo "$rootpass" | sed -r 's/\&/\\&/g');
    echo $rootpass;
    sed -i "s/root/$rootpass/g" test.txt
}
dothis "my&rootpa$$";

该脚本直到为止都能正常工作echo $rootpass,这意味着当我回显字符串时它将显示my\&rootpa\$\$

但在文件中它看起来my&rootpa$$不是my\&rootpa\$\$。脚本有什么问题?

请指教。

答案1

缺少一层额外的引号。在 sed 中,&替换(代表匹配字符串)具有特殊含义。因此,要插入文字,&您需要将其转义一次;要插入文字\&,您需要转义反斜杠 ( \\) 和与号 ( \\&),对 之前的反斜杠也一样$。这样可以得到:

#!/bin/bash
dothis(){
    rootpass="${1//\$/\\\\$}"
    rootpass="${rootpass//&/\\\\\&}"
    echo $rootpass
    sed -i "s/root/$rootpass/g" test.txt
}
dothis 'my&rootpa$$';

答案2

您应该更改此行:

dothis "my&rootpa$$";

dothis "my&rootpa\$\$";

或者使用引号代替双引号:

dothis 'my&rootpa$$';

在您的情况下,$$字符串my&rootpa$$将扩展为脚本本身的 PID。

答案3

这“dothis "my&rootpa$$"利用双引号$$末尾的“ ”将扩展为当前 PID。当我执行您的脚本时,会发生以下情况:

$./a.sh
 我的\&rootpa3595

...因为“3595”恰好是脚本的 PID。当您使用单引号 (' ') 时,将打印您期望的字符串:

$ tail -1 a.sh
 执行此“我的&rootpa$$”;

 $./a.sh
 我的\&rootpa\$\$

相关内容