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