我需要一种使用Perl或Bash来计数正则表达式捕获组中匹配项数量的方法。我可以在Powershell中执行此操作,但不能使用这两种语言。你们帮助我使Regex正常工作,但是我看到的每个示例都只是打印捕获组。打印比赛结果对我没有帮助,我需要计算每组中的比赛次数。
这里是用于正则表达式的示例数据(这是命令的输出,因此不是静态数据,也不是来自文件)
JobID Type State Status Policy Schedule Client Dest Media Svr Active PID
41735 Backup Done 0 Policy_name_here daily hostname001 MediaSvr1 8100
41734 Backup Done 0 Policy_name_here daily hostname002 MediaSvr1 7803
41733 Backup Done 0 Policy_name_here daily hostname004 MediaSvr1 7785
41732 Backup Done 0 Policy_name_here daily hostname005 MediaSvr1 27697
41731 Backup Done 0 Folicy_name_here daily hostname006 MediaSvr1 27523
41730 Backup Done 0 Policy_name_here daily hostname007 MediaSvr1 27834
41729 Backup Done 0 Policy_name_here - hostname008 MediaSvr1 27681
41728 Backup Done 0 Policy_name_here - hostname009 MediaSvr1 27496
41727 Catalog Backup Done 0 catalog full hostname010 MediaSvr1 27347
41712 Catalog Backup Done 0 catalog - hostname004 30564
我不能像使用Perl 5.8.5那样使用命名捕获组
我的正则表达式
/(\d+)?\s+((\b[^\d\W]+\b)|(\b[^\d\W]+\b\s+\b[^\d\W]+\b))?\s+((Done)|(Active)|(\w+\w+\-\w\-+))?\s+(\d+)?\s+((\w+)|(\w+\_\w+)|(\w+\_\w+\_\w+))?\s+((b[^\d\W]+\b\-\b[^\d\W]+\b)|(\-)|(\b[^\d\W]+\b))?\s+((\w+\.\w+\.\w+)|(\w+))?\s+((\w+\.\w+\.\w+)|(\w+))?\s+(\d+)?/g
每个捕获组都对应于一列,我需要将捕获组的结果提取到变量中,因此我可以使用某种where {$var -eq '0'}.count
代码进行计数。假设Status -eq '0'
表示备份成功,我需要计算状态捕获组中成功备份的次数。
最终输出类似于
Statistic.SUCCESSFUL: 20
我已经使用Powershell完成了此操作,但是Perl完全不同,Bash似乎很受限制。如果有人知道如何使用这两种语言中的任何一种来完成上述工作,我将不胜感激。
问候,
DJ
答案 0 :(得分:1)
<>; # Skip header
my $successes = 0;
while (<>) {
chomp;
my @row = /.../
or do {
die("Line $. doesn't match pattern\n");
next;
};
++$successes if $row[3] eq '0';
}
您还可以命名列。
<>; # Skip header
my $successes = 0;
while (<>) {
chomp;
my %row;
@row{qw( JobID Type State Status ... )} = /.../
or do {
die("Line $. doesn't match pattern\n");
next;
};
++$successes if $row{Status} eq '0';
}
最后,如果您想将数据存储在数据结构中以供以后分析,也可以。
<>; # Skip header
my @rows;
while (<>) {
chomp;
my %row;
@row{qw( JobID Type State Status ... )} = /.../
or do {
die("Line $. doesn't match pattern\n");
next;
};
push @rows, \%row;
}
my $successes = grep { $_->{Status} eq '0' } @rows;
最后,该正则表达式模式很糟糕。我会选择这样的东西:
sub trim(_) { $_[0] =~ s/^\s++|\s++\z//rg }
my $pattern;
my @headers;
{
my $header_line = <>;
chomp($header_line);
$header_line =~ s/\bDest Media Svr\b/Dest_Media_Svr/;
$header_line =~ s/\bActive PID\b/Active_PID/;
$pattern = join '', map { "A".length($_) } $header_line =~ /\s*\S+/g;
@headers = map trim, unpack $pattern, $header_line;
}
my @rows;
while (<>) {
chomp;
my %row; @row{@headers} = map trim, unpack $pattern, $_;
push @rows, \%row;
}
my $successes = grep { $_->{Status} eq '0' } @rows;