【问题标题】:sed/ perl with special characters (@) [duplicate]带有特殊字符 (@) 的 sed/perl [重复]
【发布时间】:2018-11-09 15:41:20
【问题描述】:

我想在这行上使用 sed / perl:

perl -pi -e  "s/password/p@ssw0rd/g" <file_name>

如何让 sed/perl 忽略特殊字符,我尝试在特殊字符前添加反斜杠,但可能我弄错了,谁能给我举个例子?

【问题讨论】:

  • 对于 sed,替换字符串中唯一的特殊字符是 &amp;@ 应该不是问题。
  • 欢迎来到 SO,请在您的帖子中发布 3 个简单的内容,1- 输入示例,2- 输出示例 3- 请您努力解决 CODE TAGS 中的问题。
  • 代码字符串的双引号?有一段时间我涉足了一个 unix,但我认为单引号是首选,这样 bash 就不会改变字符串中的内容。
  • 如果我们将值作为参数(变量)传递,我们可以做同样的事情吗? CURRENTVAULE=密码 NEWVALUE=p@ssW0rd perl -pi -e 's/$CURRENTVALUE/$NEWVALUE/g' 文件名 sed -i '' -e 's/$CURRENTVALUE/$NEWVALUE/g'

标签: regex unix sed


【解决方案1】:

@ 仅对 Perl 是特殊的,而不是 sed,因此在这种情况下您可以简单地使用 sed

sed -i -e 's/password/p@ssw0rd/g' filename     # GNU sed
sed -i '' -e 's/password/p@ssw0rd/g' filename  # BSD sed

在从 shell 向命令传递代码时,您应该养成使用单引号的习惯,因为在命令看到之前,shell 不会修改任何代码。如果你这样做,那么反斜杠 at 符号将适用于 Perl:

perl -pi -e  's/password/p\@ssw0rd/g' filename

您还可以在替换表达式中使用单引号作为分隔符,这会导致包含的表达式按字面意思解释而没有扩展;如果你回到 shell 中的双引号,那就更容易了:

perl -pi -e "s'password'p@ssw0rd'g" filename

但是如果你可能需要担心那里的shell扩展,你需要用单引号引用shell中的代码字符串使用单引号作为分隔符,这很尴尬你可能最好只使用 at 符号上的反斜杠:

perl -pi -e  's'\''password'\''p@ssw0rd'\''g' filename # POSIX shell
perl -pi -e  $'s\'password\'p@ssw0rd\'g' filename      # bash/ksh/zsh ANSI string

要在 cmets 中回答您的问题,如果您想让新旧字符串动态参数作为变量传递,它们将是 $ENV{varname} 而不仅仅是 Perl 中的 $varname,您必须区别对待它们。您不再需要担心替换值的插值(因为您只需要它的一个级别),但您必须担心模式端的特殊正则表达式字符,这意味着您需要放置 \Q... \E 围绕您要查找的内容:

CURRENTVALUE=password NEWVALUE=p@ssw0rd perl -pi -e 's/\Q$ENV{CURRENTVALUE}\E/$ENV{NEWVALUE}/g' filename

...也就是说,除非您希望 $CURRENTVALUE 的值能够成为正则表达式而不仅仅是文字字符串。但你必须选择一个。

【讨论】:

  • 好点,@glennjackman。已添加。
  • 我不知道s'''——这真的很酷。
  • 如果我们将值作为参数传递,我们可以做同样的事情吗? CURRENTVAULE=密码 NEWVALUE=p@ssW0rd perl -pi -e 's/$CURRENTVALUE/$NEWVALUE/g' 文件名 sed -i '' -e 's/$CURRENTVALUE/$NEWVALUE/g'
【解决方案2】:

在 perl 中@ 表示一个数组变量。由于s/// 的右侧允许变量插值,s/password/p@ssw0rd/ 正在寻找“@ssw0rd”变量。

一个例子:

$ perl -pe '@ssw0rd=("a","b","c"); s/password/p@ssw0rd/g' <<INPUT
> this is my password here
> INPUT
this is my pa b c here

并且不定义数组变量,替换为空字符串:

$ perl -pi -e 's/password/p@ssw0rd/g' <<INPUT
> this is my password here
> INPUT
this is my p here

来自perldoc perlopQuote and Quote-like Operators 中的文档:

对于进行插值的构造,以“$”或“@”开头的变量将被插值。下标变量 例如 $a[3]$href-&gt;{key}[0] 也被插值,数组和哈希切片也是如此。但是方法调用如 $obj-&gt;meth 不是。

插值数组或切片按顺序插值元素,以$"的值分隔,所以等价于 插值join $", @array。 “标点”数组(例如 @*)仅在名称包含 大括号 @{*},但特殊数组 @_@+@- 被插值,即使没有大括号。

因此,在s/// 的替换部分你必须特别注意$@

【讨论】:

    猜你喜欢
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2017-05-05
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多