什么本机 Perl 代码替代了 `cut`?

What native Perl code replaces `cut`?

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

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

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

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

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

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

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

嗯,$1,$2是之前定义的变量。不加代码就说不出how/where/why,但是命令可以分解如下:

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

-d, sets the delimiter to \ (\ is used to escape the \ as it is a special character). -f, tells cut to extract the second field (what is between the first and second delimiter)

例子:

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

结果

FIELD2

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

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

uniq 将删除重复项。

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

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

</code> <code> 等是内部 Perl 变量,保存第一个、第二个等的内容。捕获 来自最近成功的正则表达式模式匹配。

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

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

if ( defined $OPTIONS ) {
    my ($method, $file) = (, );
    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;
}