什么本机 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;
}
我正在学习 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;
}