4

我目前在捕获反引号 shell 命令的输出时遇到了一个非常简单的问题。我很抱歉这个问题很简单。

我有一些排序数组(@valid_runs),我知道它包含连续的重复元素。我想使用反引号将此数组回显到 uniq。我想在一个数组中捕获 STDOUT。我试图这样做。

@unique_valids = `echo '@valid_runs' | uniq`;
print @unique_valids;

此打印语句没有产生任何结果。就此而言,这也不是。

@unique_valids = `echo '@valid_runs'`;
print @unique_valids;

我知道如何使用 uniq 和 echo。这对我来说似乎很奇怪。我认为这与 perl 数组有关,而不是正确使用这些命令。我在其他地方搜索了一下,所以请不要仅仅因为解决方案看起来微不足道而对我投反对票。感谢你的宝贵时间。

关于解决方案的说明:就处理 uniq 问题而言,TLP 的解决方案是最直接的。我相当灵活,因为所有回复都建议不要针对这个问题进行系统调用。如果 Perl 的 uniq 函数与 Unix 的 uniq 相同,那么数组应该保持排序。

如果您不关心排序结果,John Corbett 的解决方案效果很好。

4

4 回答 4

8

将系统调用用于可以通过 perl 代码轻松完成的事情并不是一个好主意。模块List::MoreUtils有一个 uniq 函数,可以满足您的要求:

use List::MoreUtils qw(uniq);

my @unique = uniq @runs;

但是,模块本身内部的子程序非常简单,就像 theglauber 的回答一样:

sub uniq (@) {
    my %seen = ();
    grep { not $seen{$_}++ } @_;
}
于 2012-08-03T20:21:30.330 回答
7

您应该将数组存储到散列中,因为散列键始终是唯一的。你可以这样做:

my %temp_hash = map { $_ => 1 } @valid_runs;
my @unique_valids = keys %temp_hash;

无论如何,这就是 perl 的做法。这里没有必要使用背部抽动(我尽量避免这些)。

于 2012-08-03T18:55:34.967 回答
5

在 perl 中很容易做到这一点。这是一种对数组进行重复数据删除的相当晦涩但有趣的方法:

@dedup = grep !$seen{$_}++ @orig_array;

通过检查 perl 函数的文档来弄清楚这是做什么的grep

如果必须使用uniq,则可能需要将每个数组元素放在单独的行中。

join("\n", @your_array)

应该做到这一点。

于 2012-08-03T18:56:51.617 回答
0
#!/usr/bin/perl
use warnings;

@a = (1, 2, 3, 3, 4, 4, 5);

$cmd = "/usr/bin/uniq <<EOF\n";
$cmd .= $_."\n" foreach (@a);
$cmd .= "EOF\n";

$result = `$cmd`;
print "Cmd: $cmd\n";
print "Result is $result";

@u = split /\n/,$result;
print "After ",join " ",@u,"\n";

This does what you ask, but theglauber's answer is still better Perl.

于 2012-08-03T20:07:27.803 回答