由于空行而导致perl脚本错误计数

时间:2014-04-23 08:11:25

标签: perl count

以下脚本基本上是捕获第二列并计算值。我遇到的唯一一个小问题是文件末尾有空行(这是值的导出方式),而且由于这些空行,脚本会被错误计算。有什么想法吗?谢谢。

my $sum_column_b = 0;
open my $file, "<", "file_to_count.txt" or die($!);

while( my $line = <$file>) {
    $line =~ m/\s+(\d+)/; #regexpr to catch second column values
    $sum_column_b += $1;
}
print $sum_column_b, "\n";

4 个答案:

答案 0 :(得分:2)

主要问题是如果正则表达式不匹配,则$ 1将保留在上一次成功匹配中收到的值。因此,每个空行都会导致前一行再次计算。

改进将是:

my $sum_column_b = 0;
open my $file, "<", "file_to_count.txt" or die($!);

while( my $line = <$file>) {
    next if $line =~ /^\s*$/;  # skip "empty" lines 
    # ... maybe skip other known invalid lines

    if ($line =~ m/\s+(\d+)/) { #regexpr to catch second column values
        $sum_column_b += $1;
    } else {
        warn "problematic line '$line'\n"; # report invalid lines
   }
}
print $sum_column_b, "\n";

else-block当然是可选的,但可以帮助注意无效数据。

答案 1 :(得分:2)

我认为主要问题已经建立,当你没有条件地依赖于正则表达式匹配时,你正在使用$1,这会导致你在不应该的时候添加值。这是另一种解决方案:

$sum_column_b += $1 if $line =~ m/\s+(\d+)/;

通常,除非您检查您希望它的正则表达式是否成功,否则不应使用$1。使用这样的东西:

if ($line =~ /(\d+)/) {
     $sum += $1;
}

或者使用直接赋值给变量:

my ($num) = $line =~ /(\d+)/;
$sum += $num;

请注意,您需要通过在变量周围添加括号来使用列表上下文,否则正则表达式将只返回1以获得成功。另请注意,与Borodin说的一样,当匹配失败时,这将给出一个未定义的值,并且您必须添加代码来检查它。

在捕获多个值时,这很方便:

my @nums = $line =~ /(\d+)/g;

答案 2 :(得分:1)

尝试将此行放在while行之后:

next if ( $line =~ /^$/ );

基本上,如果当前行没有内容,则循环到下一行。

答案 3 :(得分:0)

#!/usr/bin/perl

use warnings;
use strict;

my $sum_column_b = 0;
open my $file, "<", "file_to_count.txt" or die($!);

while (my $line = <$file>) {
  next if (m/^\s*$/); # next line if this is unsignificant
  if ($line =~ m/\s+(\d+)/) {
    $sum_column_b += $1;
  }
}
print "$sum_column_b\n";