Bash调用Perl正则替换时如何转义环境变量中的特殊字符?
解决方案
方案1:优化Perl写法(最适配现有逻辑)
Perl的正则替换语法支持自定义分隔符,无需强制使用/,换成任意非字母数字符号(比如#、|)即可完全避免路径中正斜杠的转义问题。
同时不要通过shell展开变量再传入Perl代码,直接用Perl内置的%ENV哈希读取系统环境变量,既避免多层引号、eval导致的转义冲突,也不需要硬编码路径:
perl -pi -e 's#$ENV{HOME}/_TV_rips/##g' *"$videoID".info.json
该写法完全不需要eval,也不需要转义任何路径中的正斜杠,不会出现变量展开冲突的问题。你观察到的「Perl单双引号都会展开变量」的现象是eval导致的,正常直接调用Perl时,单引号包裹的代码不会做变量展开。
方案2:使用macOS原生sed实现
macOS自带的sed加-E参数即可开启扩展正则支持,完全满足当前替换需求。注意mac版sed的-i参数需要显式指定备份后缀,不需要备份的话传空字符串即可:
sed -i '' -E "s#$HOME/_TV_rips/##g" *"$videoID".info.json
原写法报错核心原因
- 使用
eval相当于多做了一层shell解析,包裹Perl代码的单引号会被提前解析失效,导致s///的结构被$HOME展开后自带的正斜杠打断 - 强制用
/作为正则分隔符,所有路径中的/都需要转义,多层展开下转义规则会变得非常复杂
内容的提问来源于stack exchange,提问作者Kasam
相关产品推荐
相关产品推荐

