【问题标题】:perl query using -pieperl 查询使用 -pie
【发布时间】:2011-10-30 13:38:27
【问题描述】:

这行得通:

perl -pi -e 's/abc/cba/g' hellofile

但这不是:

perl -pie 's/cba/abc/g' hellofile

换句话说 -pi -e 有效,但 -pie 无效。为什么?

【问题讨论】:

    标签: perl


    【解决方案1】:

    -i 标志采用一个可选参数(如果存在,必须紧跟在它之后,而不是在单独的命令行参数中),该参数指定附加到输入文件名称的后缀,以便创建备份。写入perl -pie 's/cba/abc/g' hellofile 会导致e 被视为此后缀,并且由于e 不会被解释为正常的-e 选项,Perl 会尝试运行位于s/cba/abc/g 中的脚本,这可能不会不存在。

    【讨论】:

      【解决方案2】:

      因为-i 为备份文件采用可选扩展名,例如-i.bak,因此其他标志不能直接跟在 -i 之后。

      来自perldoc perlrun

      -i[扩展名]

      指定要编辑由 构造处理的文件 到位。它通过重命名输入文件,打开输出来做到这一点 文件,并选择该输出文件作为 print() 语句的默认值。扩展名(如果提供)用于 按照这些修改旧文件的名称以制作备份副本 规则:

      如果没有提供扩展名,则不进行备份并且当前文件是 覆盖。

      如果扩展名不包含 * ,则将其附加到末尾 当前文件名的后缀。如果扩展名确实包含一个 或多个 * 字符,然后将每个 * 替换为当前 文件名。在 Perl 术语中,您可以将其视为:

      【讨论】:

        【解决方案3】:

        perl 已经告诉你原因了 :) Try-It-To-See

        $ perl -pie " s/abc/cba/g " NUL
        Can't open perl script " s/abc/cba/g ": No such file or directory
        

        如果你使用 B::Deparse 你可以看到 perl 如何编译你的代码

        $ perl -MO=Deparse -pi -e " s/abc/cba/g " NUL
        BEGIN { $^I = ""; }
        LINE: while (defined($_ = <ARGV>)) {
            s/abc/cba/g;
        }
        continue {
            die "-p destination: $!\n" unless print $_;
        }
        -e syntax OK
        

        如果您在 perlvar 中查找 $^I,您可以了解 -i 开关 :)

        $ perldoc -v "$^I"
        
            $INPLACE_EDIT
            $^I     The current value of the inplace-edit extension. Use "undef" to
                    disable inplace editing.
        
                    Mnemonic: value of -i switch.
        

        现在如果我们重温第一部分,添加一个额外的 -e,然后添加 Deparse,解释 -i 开关

        $ perl -pie -e " s/abc/cba/g " NUL
        Can't do inplace edit: NUL is not a regular file.
        
        $ perl -MO=Deparse -pie -e " s/abc/cba/g " NUL
        BEGIN { $^I = "e"; }
        LINE: while (defined($_ = <ARGV>)) {
            s/abc/cba/g;
        }
        continue {
            die "-p destination: $!\n" unless print $_;
        }
        -e syntax OK
        

        真的是把 e in -pie 当作扩展名吗?我想是的

        $ perl -MO=Deparse -pilogicus -e " s/abc/cba/g " NUL
        BEGIN { $^I = "logicus"; }
        LINE: while (defined($_ = <ARGV>)) {
            s/abc/cba/g;
        }
        continue {
            die "-p destination: $!\n" unless print $_;
        }
        -e syntax OK
        

        如有疑问,Deparse 或 Deparse,-p

        【讨论】:

          猜你喜欢
          • 2012-10-19
          • 2013-01-07
          • 2013-03-30
          • 2011-10-06
          • 2013-04-02
          • 1970-01-01
          • 1970-01-01
          • 2014-02-17
          • 1970-01-01
          相关资源
          最近更新 更多