1

我想将几个单行移到一个脚本中。

例如:

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

以上对我来说效果很好,但代价是两个磁盘 I/O 操作。

我想将上述逻辑移动到单个脚本中,以便所有替换都通过文件打开和编辑一次来实现。

EDIT1:根据您的建议,我在一个脚本中编写了这个片段,当从 Windows 批处理文件调用它时,它只会挂起:

#!/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:好的,这就是我实施您的建议的方式。奇迹般有效!

批处理文件

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;
}

非常感谢所有做出贡献的人。

4

2 回答 2

8

-p参数包装为-E

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

所以,把所有的论点-E放到while

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

-i设置$^I变量,它开启了一些特殊的魔法处理ARGV

$^I = "bak";

为那个版本的-EPerl 打开了新特性。您可以通过指定版本来做到这一点:

use v5.10;

但是,您不会使用任何加载的东西,至少在您向我们展示的内容中。

如果您想查看单线所做的一切,请-MO=Deparse在其中输入:

% 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
于 2012-08-08T06:03:23.983 回答
1

您可以将参数放在 #! 线。Perl 会读取它们,即使在 Windows 上也是如此。

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

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

或者您可以像@ephemient 在评论中所说的那样将其保留为单行。

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

-i+-p基本上在你的程序周围放置了一个 while 循环。每一行都以 形式出现$_,您的代码将运行,并$_在最后打印出来。重复。因此,您可以拥有任意数量的语句。

于 2012-08-08T06:01:01.777 回答