perl query using -pie

前端 未结 3 530
无人及你
无人及你 2021-01-11 23:47

This works:

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

But this does not:

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

相关标签:
3条回答
  • 2021-01-11 23:58

    perl already tells you why :) 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
    

    If you use B::Deparse you can see how perl compiles your code

    $ 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
    

    If you lookup $^I in perlvar you can learn about the -i switch :)

    $ 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.
    

    Now if we revisit the first part, add an extra -e, then add Deparse, the -i switch is explained

    $ 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
    

    Could it really be that e in -pie is taken as extension? I guess so

    $ 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
    

    When in doubt, Deparse or Deparse,-p

    0 讨论(0)
  • 2021-01-12 00:01

    The -i flag takes an optional argument (which, if present, must be immediately after it, not in a separate command-line argument) that specifies the suffix to append to the name of the input file for the purposes of creating a backup. Writing perl -pie 's/cba/abc/g' hellofile causes the e to be taken as this suffix, and as the e isn't interpreted as the normal -e option, Perl tries to run the script located in s/cba/abc/g, which probably doesn't exist.

    0 讨论(0)
  • 2021-01-12 00:09

    Because -i takes an optional extension for backup files, e.g. -i.bak, and therefore additional flags cannot follow directly after -i.

    From perldoc perlrun

    -i[extension]

    specifies that files processed by the <> construct are to be edited in-place. It does this by renaming the input file, opening the output file by the original name, and selecting that output file as the default for print() statements. The extension, if supplied, is used to modify the name of the old file to make a backup copy, following these rules:

    If no extension is supplied, no backup is made and the current file is overwritten.

    If the extension doesn't contain a * , then it is appended to the end of the current filename as a suffix. If the extension does contain one or more * characters, then each * is replaced with the current filename. In Perl terms, you could think of this as:

    0 讨论(0)
提交回复
热议问题