在 shell 中无法转义单引号

在 shell 中无法转义单引号

我正在尝试编写一个命令来对目录中的一批 php 文件进行 perl 替换。我要替换的字符串中有单引号,我无法让它正确地转义 shell。

我尝试回显带有未转义的引号的字符串,以查看 perl 会得到什么:

echo 's/require_once\('include\.constants\.php'\);/require_once\('include\.constants\.php'\);require_once\("\./functions/include\.session\.inc\.php"\);/g'

并且结果中没有单引号:

s/require_once\(include.constants.php\);/require_once\(include.constants.php\);require_once\("\./functions/include\.session\.inc\.php"\);/g

但是,当我尝试逃避单引号时:

echo 's/require_once\(\'include\.constants\.php\'\);/require_once\(\'include\.constants\.php\'\);require_once\("\./functions/include\.session\.inc\.php"\);/g'

我收到完成命令的提示:

>

我希望它解析的是:

s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\("\./functions/include\.session\.inc\.php"\);/g

我究竟做错了什么?

答案1

在外面使用"而不是,那么您只需要在表达式内部转义两个。'"

echo "s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\(\"\./functions/include\.session\.inc\.php\"\);/g"

答案2

单引号字符串内不会发生任何类型的扩展或求值,甚至反斜杠转义也不会。正如 Nifle 和 canen 所发布的,请改用双引号,并转义双引号而不是单引号。但是,您只需要为了 shell 的利益而转义它们。如果您打算s///直接在 perl 脚本中使用它,则无需转义,因为您通常不会将其括s///在引号中。

此外,s///由于替换字符串中有分隔符,因此操作将失败/。可以使用反斜杠转义以下斜杠/functions/include

s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\("\.\/functions\/include\.session\.inc\.php"\);/g

或选择不同的分隔符:

s@require_once\('include.constants.php'\);@require_once\('include.constants.php'\);require_once\("\./functions/include\.session\.inc\.php"\);@g

答案3

为什么不使用双引号?

"s/require_once\('include.constants.php'\);/require_once\('include.constants.php'\);require_once\("\./functions/include\.session\.inc\.php"\);/g"

答案4

您使用单引号对单引号进行转义。例如,假设您想要使用以下消息进行 git 提交:已更新 BaseActiveRecord 的 save() 方法。

为此,请运行以下命令(请注意,我使用单引号转义了单引号)。

git commit -m 'Updated BaseActiveRecord''s save() method.'

您还可以使用双引号(而不是转义单引号)来实现您的目标:

git commit -m "Updated BaseActiveRecord's save() method."

但是,请注意命令行上的双引号会导致某些内容扩展(即 $vars)。希望这能有所帮助。

相关内容