【问题标题】:Variable substitution in Perl with Perl special charactersPerl 中的变量替换与 Perl 特殊字符
【发布时间】:2021-07-11 05:24:39
【问题描述】:

我想用 Perl 替换包含 @ 字符的子字符串,如下面的 sed 命令:

substitution='newusername@anotherwebsite.com'
sed 's/oldusername@website.com/'"${substitution}"'/g' <<< "The current e-mail address is oldusername@website.com"

目前,无论我使用 Perl 而不是 sed 或 awk,我都会先将 \ 替换为 \\,将 / 替换为 \/,将 $ 替换为 \$,将 @ 替换为 \@;例如

substitution='newusername@anotherwebsite.com'
substitution="${substitution//\\/\\\\}"
substitution="${substitution//\//\\/}"
substitution="${substitution//$/\\$}"
substitution="${substitution//@/\\@}"
perl -pe 's/oldusername\@website.com/'"${substitution}"'/g' <<< "The current e-mail address is oldusername@website.com"

我已阅读有关使用单引号的信息(如下基于sed/ perl with special characters (@)),但我想知道是否有任何其他方法可以使用正斜杠来做到这一点?

substitution='newusername@anotherwebsite.com'
perl -pe "s'oldusername@website.com'"${substitution}"'g" <<< "The current e-mail address is oldusername@website.com"

另外,Perl 中除了$@% 之外还有特殊字符(以及为什么不需要转义%)?

【问题讨论】:

    标签: bash perl sed


    【解决方案1】:

    最简洁的方法是将值传递给 Perl,因为它可以正确处理替换模式和替换中的变量。使用单引号,这样 shell 的变量扩展就不会干扰。您可以使用-s 选项(在perlrun 中解释)。

    #!/bin/bash
    pattern=oldusername@website.com
    substitution=newusername@anotherwebsite.com
    perl -spe 's/\Q$pat/$sub/g' -- -pat="$pattern" -sub="$substitution" <<< "The current e-mail address is oldusername@website.com"
    

    或通过环境将值传播到 Perl。

    pattern=oldusername@website.com
    substitution=newusername@anotherwebsite.com
    pat=$pattern sub=$substitution perl -pe 's/\Q$ENV{pat}/$ENV{sub}/g' <<< "The current e-mail address is oldusername@website.com"
    

    请注意,您需要在调用 Perl 之前分配这些值,或者您需要 export 它们才能将它们传播到环境中。

    \Qquotemeta 应用于模式,即它转义所有特殊字符,以便按字面意思解释它们。

    不需要反斜杠%,因为哈希不会插入双引号或正则表达式中。

    【讨论】:

    • @TLP:“更容易”是什么意思?您需要在调用 Perl 之前 export 或分配它们,并且您需要访问哈希以获取值。
    • @TLP:添加了 %ENV 用法。
    • @TLP,为您的attention。祝您有美好的一天。 :)
    • @TLP "你真的需要在 bash 中使用 export 变量,然后才能在 Perl 中的 %ENV 中访问它们,即使它们是在同一个 shell 脚本中定义的? i>" -- export-ing 使它们成为“全局”(环境)变量,而仅仅赋值使它们成为“本地”,而不是传播到子进程;见docs。但是分配 in the same statement 有效。在 bash 中:v=7; perl -wE'say $ENV{v}' 不起作用(没有 ; 它起作用)。所以需要export,除非它总是在同一个语句中设置和使用
    • @Gerhard 我打算将同一页面链接到您,其中显示“哈希变量”。但我认为这是一条支线,不值得追求。是的,我们可以移除 cmets。
    猜你喜欢
    • 2010-12-19
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2011-03-10
    相关资源
    最近更新 更多