我正在尝试计算文本字符串的出现次数。
下面的 Perl 代码在找到某些类型的文件时打印一条语句(文本字符串),我需要计算它打印字符串的次数。
elsif ($elt =~ /DELETE_.+\.XML/) {
print " <-- Delete XMLs !!";
}
我只是想学习 perl 而我不是程序员!所以请解释任何答案。
我不想插入、排序或合并,只是计数。
我正在尝试计算文本字符串的出现次数。
下面的 Perl 代码在找到某些类型的文件时打印一条语句(文本字符串),我需要计算它打印字符串的次数。
elsif ($elt =~ /DELETE_.+\.XML/) {
print " <-- Delete XMLs !!";
}
我只是想学习 perl 而我不是程序员!所以请解释任何答案。
我不想插入、排序或合并,只是计数。
如果要计算目录中名称匹配的所有文件/DELETE_.+\.XML/
,我会这样做:
打开目录。
在 Perl 中,这是通过
opendir my $directory, "path/to/dir" or die "Error while opening: $!";
然后,$directory
是一个表示该目录句柄的变量。
获取目录中的所有文件。
在 Perl 中,我们可以使用以下readdir
函数:
my @files = readdir $directory;
这会将其所有内容读$directory
入一个名为@files
.
选择与模式匹配的所有文件。
在 Perl 中,您可以选择满足特定条件的元素grep
:
my @interesting_files = grep {/DELETE_.+\.XML/} @files;
# ^--output ^--a condition--^ ^--source
我们将条件括在花括号内。它可以包含任意代码,但我们将在这里放置一个正则表达式。grep
是一种数据过滤器。
我们计算@interesting_files
.
Perl 有一个上下文的概念。有标量上下文和列表上下文。函数和变量的行为各不相同。如果在标量上下文中使用数组,则返回该数组中的元素数。我们可以使用函数强制标量上下文scalar
:
my $count = scalar @interesting_files;
这共同构成了以下代码:
opendir my $directory, "path/to/dir" or die "Error while opening: $!";
my @files = readdir $directory;
my @interesting_files = grep {/DELETE_.+\.XML/} @files;
my $count = scalar @interesting_files;
如果我们省略不必要的变量并使用隐式上下文,这可以简化为以下两行。
opendir my $directory, "path/to/dir" or die "Error while opening: $!";
my $count = grep {/DELETE_.+\.XML/} readdir $directory;
但是,请注意,$count
只有在我们离开封闭块 ( {...}
) 之前它才可见。如果您需要$count
在此块之外,则必须在使用它的最外层范围内声明它。或者,您根本不使用,但这有缺点。my
my
真正优雅的解决方案使用以下glob
功能:
my $count =()= glob "DELETE_*.XML";
这将手动目录打开抽象化,并使用 Unix shell 熟悉的通配语法。这些不是传统的正则表达式!=()=
伪运算符可以读作count- of 。它在右侧强加列表上下文,但允许左侧具有标量上下文。
elsif ($elt =~ /DELETE_.+.XML/) {
print " <-- Delete XMLs !!";
$count++; # Count number of times string is printed
}
以下应计算匹配行:
use strict;
use warnings;
my $count = 0;
for (<>) {
$count++ if /line-matches/;
}
print "count: $count\n";
如果将其放在文件 count.pl 中,则可以将其运行为:
perl count.pl file1 file2 file3 ...
如果您需要在管道中使用它,它也应该可以工作:
ls *.XML | perl count.pl