У меня есть такие данные:
Re: Building A
Month
kWh
1
100
2
110
3
105
Re: Building B
Month
kWh
1
200
2
210
3
205
Я хотел бы преобразовать его в несколько текстовых файлов по одному для каждого здания. Мой план:
Для задачи (1) я попытался использовать флип-флоп-оператор следующим образом:
while( <DATA> ) {
next unless /^Re: Building A/ .. /^Re: Building B/;
my $line = $_;
print $line;
}
Но это не работает, потому что выше будет отображаться только данные для построения A. Данные для нескольких зданий (около 50 из них), поэтому мне нужно сделать это несколько рекурсивно. Я не стал выполнять задачу (2).
Любая помощь будет оценена.
Я бы сделал что-то вроде этого:
#!/usr/bin/perl
use strict;
use warnings;
my %buildings;
while (<DATA>) {
chomp;
$buildings{$1} = [] if /^Re: Building ([AB])/;
push @{$buildings{$1}}, $_ if $_;
}
while (my ($building, $data) = each %buildings) {
open(my $out, '>', "$building.txt") or die "Unable to open file for writing: $!\n";
for my $i (1 .. $#$data / 2) {
print $out sprintf "%s\t%s\n", $data->[$i*2-1], $data->[$i*2];
}
close $out;
}
a.txt:
Month kWh
1 100
2 110
3 105
b.txt:
Month kWh
1 200
2 210
3 205
Я думаю, что вам может быть хорошо с таблицей, поэтому я покажу вам, как делать то, что вы просите, и то, что я думаю, будет хорошо.
$name = "";
$data = {};
open(IN, "build.txt");
foreach my $line (<IN>){
if($line =~ /Re: (.*)\n/) { # get building name
$name = $1;
$name =~ s/ /_/;
$data->{$name} = []; # link to empty array
} else {
# make a new list and return to a list
@{$data->{$name}} = (@{$data->{$name}}, $line); # add line to current building data
}
}
close IN;
#
# write on file for each
#
foreach my $name (keys %{$data}){
open(OUT, ">$name.txt");
foreach my $line (@{$data->{$name}}){
print OUT $line;
}
close OUT;
}
#
# or write into one file as a table
#
open(OUT, ">tabledata.txt");
foreach my $name (keys %{$data}){
# because the data was not filtered on import we filter it now
my $flag = 0;
my @data;
foreach my $line (@{$data->{$name}}){
if($line =~ /kWh/) {
$flag = 1;
} elsif($line =~ /^\n$/){ # skip blanks
} elsif($flag == 1) { # skip the counters
$flag++;
} elsif($flag > 1) {
chomp($line);
@data = (@data, $line);
$flag = 1;
}
}
# print pretty rows
my $format = "%20s" . ("%10d" x @data);
print OUT sprintf($format, $name, @data) . "\n";
}
close OUT;
Это создает файл для каждого здания с именем здания. Примером файла Building_A.txt является:
Month
kWh
1
100
2
110
3
105
И файл таблицы называется tabledata.txt и выглядит так:
Building_A 100 110 105
Building_B 200 210 205
В python я проанализировал текстовый файл в структуре данных, а затем вывел его с помощью asciitables. В идеале вы на самом деле не будете манипулировать строками напрямую, а скорее разбираться, а затем показывать как отдельные действия.
Как именно вы выполняете синтаксический анализ, зависит от таких факторов, как регулярность формата файла и того, нужно ли вам терпимо относиться к ошибкам или опечаткам в файле.