计算有条件的行数

Counting number of lines with conditions

这是我的脚本count.pl,我正在尝试计算文件中的行数。 脚本代码:

chdir $filepath;

if (-e "$filepath"){
$total = `wc -l < file.list`;
printf "there are $total number of lines in file.list";
}

我可以获得正确的输出,但我不想计算空行和文件中以 # 开头的任何内容。有什么想法吗?

使用sed过滤掉单个文件中“不需要的”行:

sed '/^\s*#/d;/^\s*$/d' infile | wc -l

显然,您也可以将 infile 替换为文件列表。

perl -ne '$n++ unless /^$|^#/ or eof; print "$n\n" if eof'

也适用于多个文件。

 perl -ne '$n++ unless /^$|^#/ or eof; END {print "$n\n"}'

单个文件更好。

open(my $fh, '<', $filename);
my $n = 0;
for(<$fh>) { $n++ unless /^$|^#/}
print $n;

因为这是一个 Perl 程序,已经打开文件并读取它,过滤掉不符合

的行
open my $fh, '<', $filename or die "Can't open $filename: $!";
my $num_lines = grep { not /^$|^\s*#/ } <$fh>; 

其中 $filename 是“file.list”。如果“空行”是指仅包含空格的行,则将正则表达式更改为 /^\s*$|^\s*#/。请参阅 grep, and perlretut 了解其条件中使用的正则表达式。

当控件退出当前范围时,该文件句柄 $fh 将关闭,或者在不再需要处理文件后添加 close $fh;。或者,用 do

将其包装在一个块中
my $num_lines = do { 
    open my $fh, '<', $filename or die "Can't open $filename: $!";
    grep { not /^$|^\s*#/ } <$fh>; 
};

如果打开该文件的唯一目的是计算行数,那么这样做是有意义的。

还有一件事:应该始终检查像 chdir 这样的操作,然后也不需要对竞争敏感的 if (-e $filepath)。一共

# Perhaps save the old cwd first so to be able to return to it later
#my $old_cwd = Cwd::cwd;
chdir $filepath or die "Can't chdir to $filepath: $!";

open my $fh, '<', $filename or die "Can't open $filename: $!";
my $num_lines = grep { not /^$|^\s*#/ } <$fh>; 

一些其他注意事项:

  • 没有理由printf。对于所有正常打印,请使用 say,为此您需要在程序开头使用 use feature qw(say);。请参阅 feature 杂注

  • 为了以防万一,请允许我添加:每个程序都必须在开头

    use warnings;
    use strict;
    

也许问题中代码的初衷是让程序尝试一个不存在的位置,而不是死掉?无论如何,一种保持 -e 测试的方法,正如

所要求的
#my $old_cwd = Cwd::cwd;
chdir $filepath or warn  "Can't chdir to $filepath: $!";

my $num_lines;
if (-e $filepath) { 
    open my $fh, '<', $filename or die "Can't open $filename: $!";
    $num_lines = grep { not /^$|^\s*#/ } <$fh>; 
}

如果 chdir 失败,我仍然添加警告。如果您真的不想要它,请将其删除。我还添加了一个分配了行数的变量声明,my $total_lines;。如果它在您的实际代码中较早声明,那么当然会在此处删除该行。

解决方法很简单,没有任何魔法。

use strict;
use warnings;
use feature 'say';

my $count = 0;

while( <> ) {
    $count++ unless /^\s*$|^\s*#/;
}

say "Total $count lines";

参考: <>