【问题标题】:What happens in each of these Perl one-liners?在这些 Perl 单行代码中会发生什么?
【发布时间】:2014-02-01 13:26:21
【问题描述】:

我正在尝试理解 cli 中的 perl one 衬里。
例如,如果我需要在文件中进行替换:

perl -e 's/eat/read/g' file  

什么都没有发生。

如果我这样做:

perl -i -e 's/eat/read/g' file

文件也没有任何反应。

只有当我这样做时:

perl -p -i -e 's/eat/read/g' file

文件中的内联替换发生了。
如果我这样做了

perl -n -i -e 's/eat/read/g' file

文件变空!

谁能解释一下不同之处以及每种情况会发生什么?

【问题讨论】:

  • perlrun 会告诉您它们各自的作用。
  • 第一个什么都不做,因为没有设置任何标志来调用将文件提供给脚本的行为。第二个出于同样的原因什么也不做。第三种方法有效,因为您告诉 Perl 遍历文件并将输出作为就地编辑发送到文件。 ...并且您告诉 Perl 您总是希望为每一行输出 $_ 。第四个失败,因为尽管您正在遍历文件并进行就地编辑,但您从未向文件发送任何输出,因此它变为空。

标签: regex perl command-line-interface


【解决方案1】:

B::Deparse 模块将显示开关对您的 perl 代码的作用,

perl -MO=Deparse -e 's/eat/read/g' file
s/eat/read/g;

这里没什么有趣的,你的代码按原样执行。

perl -MO=Deparse -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
s/eat/read/g;

好的,-i 更改了全局变量 $^I 用于内联编辑,但没有读取文件,这里也没有循环。

perl -MO=Deparse -p -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}
continue {
    print $_;
}

所以-p 添加了while(){} 循环,其中每一行都被读取、由您的代码更改并再次写入文件(在continue{} 块中打印)

perl -MO=Deparse -n -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}

所以-n 没有带有-p 开关的continue{} 块,如果您想对文件进行所需的更改,则必须在s/// 替换后手动打印(否则不会打印任何内容并且正如您已经注意到的那样,您的文件结尾被截断了)。

【讨论】:

    【解决方案2】:

    摘自perl -h

    Usage: perl [switches] [--] [programfile] [arguments]
      -e program        one line of program (several -e's allowed, omit programfile)
      -i[extension]     edit <> files in place (makes backup if extension supplied)
      -n                assume "while (<>) { ... }" loop around program
      -p                assume loop like -n but print line also, like sed
    

    -i 就地编辑文件时,您还需要使用-p 或显式(使用-n's/eat/read/; print' 将某些内容打印到文件中

    就地编辑的常见模式是

    perl -pi.bak -e 's/eat/read/g' file
    

    这将按预期修改您的文件,保存后缀为.bak的备份

    【讨论】:

    • 但是当我使用带有perl -p -e '...'的sn-p时,什么都没有打印出来
    • @Jim - 给定file,内容为abcperl -p -e 's/a/X/' file 打印Xbc。仔细检查您的文件和命令行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2016-06-09
    相关资源
    最近更新 更多