我有一个文本文件,看起来与此类似:
1 Bob J Smith 3 4 2 1 10 8
2 James Miller 5 3 82 3 44 1
3 ...
我想要达到的目的是只在每行中添加数字并给出每人总数。但是必须跳过第一个数字(在名称之前)和文本并且只计算数字。我的@lines
数组包含我需要使用的文件。
my $total;
my @row;
foreach(@lines){
@row=split;
$total=0;
$total+=$_ for @row[3..$#row];
print "$row[0]: $total\n";
}
print "$row[0]: $total\n";
答案 0 :(得分:1)
将文件读入数组然后迭代数组通常不仅仅是迭代文件。您不应该将整个文件读入内存,除非您出于某种原因需要随机访问数据
除非您实际上有标签将名称与周围字段分开,否则您的数据格式不是很有用。否则,无法区分名称的其他部分
此程序通过将每行的最后两个字段重复加在一起,直到最后一个字段,但其中一个不是数字。它假定每一行的最后一个字段始终是数字,并且不对此
进行任何检查use strict;
use warnings 'all';
while ( <DATA> ) {
my @fields = split;
while ( $fields[-2] =~ /\A\d+\z/ ) {
push @fields, pop(@fields) + pop(@fields);
}
print "@fields\n";
}
__DATA__
1 Bob J Smith 3 4 2 1 10 8
2 James Miller 5 3 82 3 44 1
1 Bob J Smith 28
2 James Miller 138
答案 1 :(得分:0)
或者使用正则表达式将每一行划分为名称和数字,然后将数字合计。
while (<DATA>)
{
chomp;
next if /^$/;
my $total = 0;
/\d+ ([A-Za-z ]+) ([\s\d]+)$/;
my @numbers = split(' ', $2);
$total += $_ for (@numbers);
print "$1: $total\n";
}
__DATA__
1 Bob J Smith 3 4 2 1 10 8
2 James Miller 5 3 82 3 44 1
3 Allan X Smith 5 4 82 3 44 2
答案 2 :(得分:0)
可能更简单,更直接:
use strict;
use warnings;
use List::Util 'sum';
while ( <DATA> ) {
my @row = split;
print shift @row, ' '; # print row number
while (@row and $row[0] !~ /^\d+$/) { # print name
print shift @row, ' ';
}
print sum(@row, 0), $/;
}
__DATA__
1 Bob J Smith 3 4 2 1 10 8
2 James Miller 5 3 82 3 44 1