什么本机Perl代码取代了“cut”?

什么本机Perl代码取代了“cut”?,perl,cross-platform,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多个命名参数

我在学习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) 看起来最终的结果是找到的
cut
的唯一实例的
$count


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

那么$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")
通过管道的其余命令如下所示:

my $count = `cut -d\\  -f 2 $file | sort | uniq | wc -l`;
sort
将获取字段列表并按降序排列

uniq
将删除重复项

wc-l
将给出列表中条目数的最终总数(实际上是行数)


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

$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;
}
if(定义的$OPTIONS){
我的($method,$file)=($1,$2);

打开我的$fh,'您需要向我们展示函数中在此之前的内容。我猜,
$1
$2
来自字符串匹配。至于
剪切
,请参见。谢谢。Perl有很多疯狂的保留变量。我不确定$1,$2是否属于该类别。它们现在变得无关紧要。Re手册页是我了解分隔符、字段和$file值。我正在寻找本机Perl代码来替换它。它是否像open()一样直接,regex是第二个字段,将结果添加到散列中,并在完成时将散列大小报告为
$count
?或者Perl有更好的方法来做到这一点吗?“数百兆字节”还不错。500MB从磁盘读取大约需要5秒钟,提取第二个字段的相关处理时间将是微不足道的。我看不出
排序的意义,尤其是在
uniq
之前,如果结果只是行计数的话。另外,
排序
按升序排序。MattSizzle。我得到了mos我正试图用原生Perl替换这一行,以便它在Windows上运行。但是,我不熟悉Perl。谢谢,Borodin。这很有效。至于“真实版本”…这是真实的版本。它是2300行代码中的三行。其他变量在其函数中的其他位置使用。这些行设置$count,这也在其他地方使用。如果没有外部引用,此脚本现在将在非Posix系统上运行,而无需
cut
uniq
wc
,等等c、 但是可能会慢一点。这很好。是的。在一个200行的小测试数据集上进行测试。在生产环境中进行测试需要更长的时间。正如我所写的,它可能会稍微快一点。但是
$count
变量只能在
my
声明和下一行的右括号之间访问。它不可用在
if
旁边。这同样适用于您的原始代码。是的,在
if
中有两行代码使用了
$count
值。为了简洁起见,我从这个示例中删除了它们。感谢您的澄清。