Grep元素来自输出中存在的数组

时间:2016-09-07 12:06:51

标签: arrays perl grep

有没有办法使用grep只查找特定数组中存在的元素? 例如:

my @IPS ={"10.20.30","12.13.14","30.40.50"};

my $cmd = `netstat -Aa | grep -c IPS[0] OR IPS[1] OR IPS[2]  `

print "$cmd";

我希望cmd返回netstat命令输出中存在的IPS(仅在数组中找到的数量)。 我知道我可以使用" | "或条件,但假设我不知道数组中元素的数量。

2 个答案:

答案 0 :(得分:2)

您的@IPS数组不包含您认为包含的内容。我想你可能想要:

my @IPS = ("10.20.30","12.13.14","30.40.50");

我写的是:

my @IPS = qw(10.20.30 12.13.14 30.40.50);
  

我知道我可以使用“|”或条件,但假设我不知道数组中元素的数量

我认为这根本不重要。

# Need quotemeta() to escape the dots
my $IP_str = join '|', map { quotemeta $_ } @IPS;
my $IP_re  = qr/$IP_str/;

# Keep as much of the processing as possible in Perl-space
my @found = grep { /$IP_str/ } `netstat -Aa`;
say scalar @found;

正则表达式的替代方法是将@IPS转换为哈希值。

my %IP = map { $_ => 1 } @IPS;
my @found = grep { $IP{$_} } `netstat -Aa`;
say scalar @found;

更新:实际上,最后一个示例不起作用。在匹配哈希之前,您需要从netstat输出中提取IP地址。但是我把它留在那里,以防它激励任何人扩展它。

答案 1 :(得分:0)

快速而肮脏的方法是使用perl中的$"变量:

my @IPS =("10.20.30","12.13.14","30.40.50");
local $"='|';
my $cmd = `netstat -Aa | grep '@IPS' | wc -l`
print "$cmd";

这个想法是$"控制在一些引号内插入时数组变量的显示方式。因此,通过说$"='|',我们会将@IPS数组插入为由|分隔的元素的串联。 注意:如果您信任@IPS来源,则应该只使用此功能。如果你自己在代码中键入它。如果它来自不受信任的外部来源,上述技巧可能会很危险。

修改:如果@IPS来自不受信任的来源,您可以首先验证它

/^[\d.]+$/ or die "Invalid IP address" for @IPS;