2012-04-24 39 views
1

我有這樣一個數據:轉換線列Perl或Python

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),所以我需要做這個有點復發sively。我還沒有開始做任務(2)。

任何幫助將不勝感激。

回答

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 
0

在python中,我將解析文本文件爲數據結構,然後使用asciitables輸出它。理想情況下,您不會直接操縱字符串,而是解析,然後顯示爲單獨的操作。

解析的確切程度取決於多種因素,例如文件格式是多麼規則,以及您是否需要容忍文件中的錯誤或拼寫錯誤。

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