【问题标题】:How can I consolidate several Perl one-liners into a single script?如何将多个 Perl 单行代码合并到一个脚本中?
【发布时间】:2012-08-05 04:29:18
【问题描述】:

我想将多个单行列移动到一个脚本中。

例如:

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:根据您的建议,我在一个脚本中编写了这个 sn-p,当从 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;
}

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

【问题讨论】:

  • 你确实意识到你可以使用一个单行,对吧? perl -i.bak -pE "s/String_ABC/String_XYZ/g;s/Manhattan/New_England/g" Cities.Txt
  • 是的,但是我有 60 多个替换要执行并且通过命令行传递它们是站不住脚的。

标签: string perl substitution


【解决方案1】:

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

-E 开启了该版本 Perl 的新功能。你可以通过指定版本来做到这一点:

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

【讨论】:

    【解决方案2】:

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

    #!/usr/bin/perl -i.bak -p
    
    s/String_ABC/String_XYZ/g;
    s/Manhattan/New_England/g;
    

    或者你可以像 @ephemient 在 cmets 中所说的那样保持单线。

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

    -i + -p 基本上在你的程序周围放置了一个while循环。每行以$_ 出现,您的代码运行,$_ 在最后打印出来。重复。所以你可以有尽可能多的语句。

    【讨论】:

    • 嗯,-p 添加了 while 循环和 print 语句。 -i 与此无关,但它确实设置了 $^I。
    • shebang 行中的多个参数是不可移植的……尽管我的 Perl 二进制文件处理得很好。那是什么时候开始发生的?
    • @ephemient 我从来没有听说过把开关放在#!线,做了很久。有引用吗? Perl 将开关从 #!本身,已经有很长一段时间了,所以操作系统所做的可能是没有实际意义的。
    • 可能是当你有 #!/usr/bin/env perl 的时候。在 linux 上,它试图执行一个名为“perl ”的程序。在任何其他 unix 变体上,它使用指定的 args 执行 perl。
    • ./script.pl 中有#!/usr/bin/perl -i.bak -p 时,Linux 将运行'/usr/bin/perl' '-i.bak -p' './script.pl'(在 POSIX 下完全可以接受)。我很惊讶,但一些实验表明 Linux 上的 Perl 5.10.1 将重新拆分其关于空格的参数...
    猜你喜欢
    • 1970-01-01
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 2016-04-07
    • 2021-01-10
    • 1970-01-01
    相关资源
    最近更新 更多