什么原生Perl代码替换`cut`?

时间:2015-02-11 03:19:30

标签: perl cross-platform

我正在学习Perl,因为我编辑了一个Perl脚本,将Posix OS调用替换为本机Perl函数,以便在Windows上进行跨平台使用。这段代码让我难过:

if (defined($OPTIONS)) {
    my ($method,$file) = ($1,$2);
    my $count = `cut -d\\  -f 2 $file | sort | uniq | wc -l`;
}

1)$1$2来自哪里?此代码位于函数内部,但该函数没有任何参数。此外,脚本本身会解析70多个命名参数,因此它们不会形成命令行。

2)由于我不知道$2是什么,我不确定$file的内容。

3)无论$file的内容是什么,cut函数都会查看每行的第二个字段(由反斜杠分隔)。

4)看起来最终结果是找到$count的唯一实例的cut

考虑$file可能非常大(百万行,数百兆字节),用于替换此外部调用并获得相同$count值的最有效的本机Perl代码是什么? “有效”也是相对的。此代码位于工具链中,其他阶段可以运行2或3天。因此,如果此代码在大文件上需要5或10分钟,则不会出现问题。

2 个答案:

答案 0 :(得分:1)

$1 $2等是内部Perl变量,用于保存最近成功的正则表达式模式匹配中的第一个,第二个等捕获的内容。

这应该做你想要的。它使用散列来跟踪第二列的所有唯一值,并在读取文件时将$count设置为不同键的数量。它可能比工具链等效物稍快。请注意,它是未经测试的,因为我目前不在使用Perl的系统附近。

我希望在这段代码的真实版本中还有更多内容,因为它唯一的效果是更改在块结尾处丢弃的几个局部变量的值。

if ( defined $OPTIONS ) {
    my ($method, $file) = ($1, $2);
    open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!};
    my %count;
    ++$count{ (split /\\/, $_, 3)[1] } while <$fh>;
    my $count = keys %count;
}

答案 1 :(得分:0)

好1美元,2美元是先前定义的变量。没有额外的代码,不知道如何/在哪里/为什么,但命令可以按如下方式分解:

my $count = `cut -d\\  -f 2 $file | sort | uniq | wc -l`;
  

-d,将分隔符设置为\(\用于转义\,因为它是一个特殊字符)。 -f,告诉cut提取第二个字段(第一个和第二个分隔符之间的内容)

示例

cut -d\\ -f 2 <<< $(echo "FIELD 1\FIELD2\THE_REMAINDER")

<强>结果

FIELD2

通过管道的其余命令如下:

sort将获取字段列表并按值降序排序。

uniq将删除重复项。

wc -l将为您提供列表中条目数的最终总数(实际上是行数)

因此,为了使用基于非基于unix的解决方案进行复制,您需要通过Perl系统地完成每个步骤。这应该不难实现,所以我省略了那一部分。随意用你所尝试的内容更新你的问题,我相信会提供大量的帮助,因为这是一个非常有趣的挑战恕我直言。