我正在尝试计算文本字符串的出现次数。
我的Perl代码在找到某些类型的文件时打印一个语句(文本字符串),我需要计算它打印字符串的次数。
elsif ($elt =~ /DELETE_.+\.XML/) {
print " <-- Delete XMLs !!";
}
我只是想学习perl而我不是程序员!所以请解释任何答案。
我不想插入,排序或合并,只计算。
答案 0 :(得分:4)
如果要计算目录中名称与/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有 context 的概念。有标量上下文和列表上下文。函数和变量在每个函数中表现不同。如果在标量上下文中使用数组,则返回该数组中的元素数。我们可以使用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 。它在右侧强加了列表上下文,但允许左侧有标量上下文。
答案 1 :(得分:2)
elsif ($elt =~ /DELETE_.+.XML/) {
print " <-- Delete XMLs !!";
$count++; # Count number of times string is printed
}
答案 2 :(得分:0)
以下内容应计算匹配的行:
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