преобразование строк в столбцы в perl или python

1

У меня есть такие данные:

Re: Building A

Month
kWh
1
100
2
110
3
105


Re: Building B

Month
kWh
1
200
2
210
3
205

Я хотел бы преобразовать его в несколько текстовых файлов по одному для каждого здания. Мой план:

  1. извлекать значения между строкой разделителя здания
  2. конвертировать строки в таблицу

Для задачи (1) я попытался использовать флип-флоп-оператор следующим образом:

while( <DATA> ) {
  next unless /^Re: Building A/ .. /^Re: Building B/;
  my $line = $_;
  print $line;
}

Но это не работает, потому что выше будет отображаться только данные для построения A. Данные для нескольких зданий (около 50 из них), поэтому мне нужно сделать это несколько рекурсивно. Я не стал выполнять задачу (2).

Любая помощь будет оценена.

Теги:

3 ответа

4
Лучший ответ

Я бы сделал что-то вроде этого:

#!/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
2

Я думаю, что вам может быть хорошо с таблицей, поэтому я покажу вам, как делать то, что вы просите, и то, что я думаю, будет хорошо.

$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
0

В python я проанализировал текстовый файл в структуре данных, а затем вывел его с помощью asciitables. В идеале вы на самом деле не будете манипулировать строками напрямую, а скорее разбираться, а затем показывать как отдельные действия.

Как именно вы выполняете синтаксический анализ, зависит от таких факторов, как регулярность формата файла и того, нужно ли вам терпимо относиться к ошибкам или опечаткам в файле.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню