How can I consolidate several Perl one-liners into a single script?

僤鯓⒐⒋嵵緔 提交于 2019-12-11 09:14:11

问题


I would like to move several one liners into a single script.

For example:

perl -i.bak -pE "s/String_ABC/String_XYZ/g" Cities.Txt
perl -i.bak -pE "s/Manhattan/New_England/g" Cities.Txt

Above works well for me but at the expense of two disk I/O operations.

I would like to move the aforementioned logic into a single script so that all substitutions are effectuated with the file opened and edited only once.

EDIT1: Based on your recommendations, I wrote this snippet in a script which when invoked from a windows batch file simply hangs:

#!/usr/bin/perl -i.bak -p Cities.Txt
use strict;
use warnings;

while( <> ){
s/String_ABC/String_XYZ/g;
s/Manhattan/New_England/g;
print;
}

EDIT2: OK, so here is how I implemented your recommendation. Works like a charm!

Batch file:

perl -i.bal MyScript.pl Cities.Txt

MyScript.pl

#!/usr/bin/perl
use strict;
use warnings;

while( <> ){
s/String_ABC/String_XYZ/g;
s/Manhattan/New_England/g;
print;
}

Thanks a lot to everyone that contributed.


回答1:


The -p wraps the argument to -E with:

while( <> ) {
    # argument to -E
    print;
    }

So, take all the arguments to -E and put them in the while:

while( <> ) {
    s/String_ABC/String_XYZ/g;
    s/Manhattan/New_England/g;
    print;
    }

The -i sets the $^I variable, which turns on some special magic handling ARGV:

$^I = "bak";

The -E turns on the new features for that versions of Perl. You can do that by just specifying the version:

use v5.10;

However, you don't use anything loaded with that, at least in what you've shown us.

If you want to see everything a one-liner does, put a -MO=Deparse in there:

% perl -MO=Deparse -i.bak -pE "s/Manhattan/New_England/g" Cities.Txt
BEGIN { $^I = ".bak"; }
BEGIN {
    $^H{'feature_unicode'} = q(1);
    $^H{'feature_say'} = q(1);
    $^H{'feature_state'} = q(1);
    $^H{'feature_switch'} = q(1);
}
LINE: while (defined($_ = <ARGV>)) {
    s/Manhattan/New_England/g;
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK



回答2:


You can put arguments on the #! line. Perl will read them, even on Windows.

#!/usr/bin/perl -i.bak -p

s/String_ABC/String_XYZ/g;
s/Manhattan/New_England/g;

or you can keep it a one-liner as @ephemient said in the comments.

perl -i.bak -pE "s/String_ABC/String_XYZ/g; s/Manhattan/New_England/g" Cities.Txt

-i + -p basically puts a while loop around your program. Each line comes in as $_, your code runs, and $_ is printed out at the end. Repeat. So you can have as many statements as you want.



来源:https://stackoverflow.com/questions/11858147/how-can-i-consolidate-several-perl-one-liners-into-a-single-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!