我正在学习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分钟,则不会出现问题。
答案 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
系统地完成每个步骤。这应该不难实现,所以我省略了那一部分。随意用你所尝试的内容更新你的问题,我相信会提供大量的帮助,因为这是一个非常有趣的挑战恕我直言。