Perl 解析重复4个线组的数据
我有这样的数据Perl 解析重复4个线组的数据,perl,Perl,我有这样的数据 02/06/2014 VONS STORE -$5.95 02/06/2014 VONS STORE -$3.99 02/06/2014 VONS STORE -$3.70 02/05/2014 VONS STORE -$8.99 02/05/2014 VONS STORE -$6.97 02/04/2014 MISSION HI -$5.74 02/03/2014 R K SUSHI -$34.23 01/30/2014
02/06/2014
VONS STORE
-$5.95
02/06/2014
VONS STORE
-$3.99
02/06/2014
VONS STORE
-$3.70
02/05/2014
VONS STORE
-$8.99
02/05/2014
VONS STORE
-$6.97
02/04/2014
MISSION HI
-$5.74
02/03/2014
R K SUSHI
-$34.23
01/30/2014
MISSION HI
-$9.94
我如何将其拆分为如下所示的数据:
VONS STORE (5x): $29.6
MISSION HI (2x): $15.68
R K SUSHI (1x): $34.23
这需要在事先不了解门店或订单的情况下完成
实际上,这个问题中唯一困难的部分是将数据分为四行块–我如何才能做到这一点?一次循环一行文件,跟踪缓冲区中读取的最后四行,然后刷新:
#!/usr/bin/perl
use v5.14;
open(IN, "<", "mydata.txt");
my @lineBuffer = ();
my %prices;
my %number;
while (<IN>) {
chomp();
if (@lineBuffer < 4) {
push(@lineBuffer, $_);
} else {
my $price = @lineBuffer[3];
$price =~ s/-\$//;
$prices{@lineBuffer[2]} += $price;
$number{@lineBuffer[2]}++;
@lineBuffer = ();
}
}
for my $key (keys %number) {
say $key." (".$number{$key}."x): ".'$'.$prices{$key}
}
close(IN);
或许以下内容会有所帮助:
use strict;
use warnings;
use List::Util qw/sum/;
local $/ = '';
my %h;
while (<>) {
next if $. % 2;
push @{ $h{$1} }, $2 if /(.+)\n-?\$(.+)/;
}
print "$_ (" . @{ $h{$_} } . 'x): $' . ( sum @{ $h{$_} } ), "\n"
for sort { @{ $h{$b} } <=> @{ $h{$a} } } keys %h;
由于存在空行,因此设置了以段落模式$/=读取。通过捕获企业名称和金额,只处理偶数段。使用数组HoA的散列,其中键是业务名称,关联值是金额列表的引用
结果按金额的数量按降序排序和打印
希望这有帮助 第一个捕获匹配名称,第二个匹配金额,将其散列并打印
#!/usr/bin/perl
open(IN, "<", "data.txt");
my %r;
my %t;
my $data = join "",(<IN>);
while( $data =~ /^([^\n\d]+)\n.*?^(-?)\$([\.\d]+)/img) {
$r{$1}++;
$t{$1} += $3;
}
foreach (keys %r){
my $o = sprintf("%-15.15s(%dx): \$%02.2f",$_,$r{$_},$t{$_});
print "$o\n";
}
如果您知道怎么做,那么剩下的就是一次读取多行,直到,然后使用由存储名称键入的哈希或hashref来解析和跟踪数据。是否有某一部分您遇到了麻烦?描述您的需求、请某人为您编写代码或向您解释如何编写代码的问题与堆栈溢出无关。请确定有关编程的特定问题。包括尝试的解决方案,解释结果与预期结果的差异,以及您收到的任何错误消息。请阅读:OP以销售数量的降序显示结果。是的,它们也有格式,但我想他可以从这里开始。他还特别询问了如何一次阅读第4行。输出是如何按照OP的排序的?
#!/usr/bin/perl
open(IN, "<", "data.txt");
my %r;
my %t;
my $data = join "",(<IN>);
while( $data =~ /^([^\n\d]+)\n.*?^(-?)\$([\.\d]+)/img) {
$r{$1}++;
$t{$1} += $3;
}
foreach (keys %r){
my $o = sprintf("%-15.15s(%dx): \$%02.2f",$_,$r{$_},$t{$_});
print "$o\n";
}