我创建了一个 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\$\$