1

我正在尝试计算文本字符串的出现次数。

下面的 Perl 代码在找到某些类型的文件时打印一条语句(文本字符串),我需要计算它打印字符串的次数。

elsif ($elt =~ /DELETE_.+\.XML/) {
    print "  <-- Delete XMLs !!";
}

我只是想学习 perl 而我不是程序员!所以请解释任何答案。

我不想插入、排序或合并,只是计数。

4

3 回答 3

4

如果要计算目录中名称匹配的所有文件/DELETE_.+\.XML/,我会这样做:

  1. 打开目录。
    在 Perl 中,这是通过

    opendir my $directory, "path/to/dir" or die "Error while opening: $!";
    

    然后,$directory是一个表示该目录句柄的变量。

  2. 获取目录中的所有文件。
    在 Perl 中,我们可以使用以下readdir函数:

    my @files = readdir $directory;
    

    这会将其所有内容读$directory入一个名为@files.

  3. 选择与模式匹配的所有文件。
    在 Perl 中,您可以选择满足特定条件的元素grep

    my @interesting_files = grep {/DELETE_.+\.XML/} @files;
    #  ^--output                 ^--a  condition--^ ^--source
    

    我们将条件括在花括号内。它可以包含任意代码,但我们将在这里放置一个正则表达式。grep是一种数据过滤器。

  4. 我们计算@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在此块之外,则必须在使用它的最外层范围内声明它。或者,您根本不使用,但这有缺点。mymy


真正优雅的解决方案使用以下glob功能:

my $count =()= glob "DELETE_*.XML";

这将手动目录打开抽象化,并使用 Unix shell 熟悉的通配语法。这些不是传统的正则表达式!=()=伪运算符可以读作count- of 。它在右侧强加列表上下文,但允许左侧具有标量上下文。

于 2012-10-30T18:52:42.507 回答
2
elsif ($elt =~ /DELETE_.+.XML/) { 
   print " <-- Delete XMLs !!";
   $count++;   # Count number of times string is printed
}
于 2012-10-30T17:46:25.500 回答
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
于 2012-10-30T17:46:27.300 回答