将Perl One Liner转换为脚本

时间:2019-01-27 07:45:16

标签: regex perl

我是Vijay,我是一名学生,对学习perl脚本非常感兴趣。 我正在学习Perl on Liner。 我想编写一个perl脚本,该脚本逐行通过文件,并将每行与上一行(或下一行)进行比较,以查找前3列中的匹配值。然后我只想将前三列中的值打印一次,并将第四列的值作为新列推入。例如

1 760605 769233 15.65  
1 760605 769233 44.11  
1 760605 769233 18.5 

输出应为

1 760605 769233 15.65 44.11 18.5

为此的一个班轮是

perl -ape '$k="@F[0..2]"; $_=" $F[3]",next if $k eq $o; $_= "\n@F";$o=$k' filename

在这里,我想将此内容隐藏成脚本并运行该脚本。如果我知道如何将以上一种衬里转换为脚本,那将非常有用,我也可以对其他人实施相同的逻辑。

谢谢。

1 个答案:

答案 0 :(得分:2)

正如@Corion所说,B::Deparse在这里可以提供帮助。

$ perl -MO=Deparse -ape '$k="@F[0..2]"; $_=" $F[3]",next if $k eq $o; $_= "\n@F";$o=$k'
LINE: while (defined($_ = readline ARGV)) {
    our @F = split(' ', $_, 0);
    $k = join($", @F[0..2]);
    $_ = " $F[3]", next if $k eq $o;
    $_ = "\n@F";
    $o = $k;
}
continue {
    die "-p destination: $!\n" unless print $_;
}

将其清理成几乎等效的脚本:

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

my $o;
while ( my $line = <> ) {
    my @fields = split ' ', $line;
    my $k = "@fields[0..2]";
    if (defined $o && $k eq $o) {
        $line = " $fields[3]";
        next;
    }
    $line = "\n@fields";
    $o = $k;
} continue { print $line }