Parsing and tabulating results
<p>What is a simple and flexible way to parse and tabulate output  like the one below on a Unix system? </p>

<p>The output has multiple entries in the following format:  </p>

<pre><code>===================================================== 
======  SOLVING WITH MATRIX small_SPD ====
=================================================== 

sizes: 5,5,8

Solving with Sparse LU AND COLAMD ... 
COMPUTE TIME : 8.9287e-05
SOLVE TIME : 1.0663e-05
TOTAL TIME : 9.995e-05
REL. ERROR : 2.30263e-18


Solving with BiCGSTAB ... 
COMPUTE TIME : 4.113e-06
SOLVE TIME : 1.853e-05
TOTAL TIME : 2.2643e-05
REL. ERROR : 1.34364e-10

ITERATIONS : 2
</code></pre>

<p>This should be tabulated as (or similar):</p>

<pre><code>Matrix      Sizes         Solver             Compute    Solve         Total       Rel Error
small_SPD   5,5,8  Sparse LU AND COLAMD   8.9287e-05   1.0663e-05   9.995e-05   2.30263e-18   
small_SPD   5,5,8        BiCGSTAB          4.113e-06   1.853e-05    2.2643e-05  1.34364e-10
</code></pre>

<p>If you're just parsing an output, I'd tackle it like this:</p>

<pre><code>#!/usr/bin/env perl
use strict;
use warnings;

#set paragraph mode - look for empty lines between records.
local $/ = '';

#init the matrix/size vars. 
my $matrix;
my $sizes;

#output order    
my @columns = ( "COMPUTE TIME", "SOLVE TIME", "TOTAL TIME", "REL. ERROR" );

#Column headings.
print join "\t", "matrix", "sizes", "solver", @columns,"\n";

#iterate the data. 
#note - &lt;&gt; is a magic file handle that reads STDIN or 'files specified on command line'
#that's just like how sed/grep/awk do it. 
while (&lt;&gt;) {
   #find and set the matrix name
   #note conditional - this only appears in the 'first' record. 
   if (m/MATRIX (\w+)/) {
      $matrix = $1;
   }
   #find and set the sizes. 
   if (m/sizes: ([\d\,]+)/) {
      $sizes = $1;
   }
   #multi-line pattern match to grab keys and values. 
   #this then maps neatly into a hash. 
   my %result_set = m/^(\w+).*: ([\d\.\-e]+)/gm;

   #add the solver to the 'set':
   #and use this test to check if this 'record' is of interest. 
   #skipping the "ITERATIONS" line. 
   my ( $solver ) =  m/Solving with (.*) .../ or next;
   #print it tab separated.  
   print join "\t", $matrix, $sizes, $solver, @result_set{@columns}, "\n";
}
</code></pre>

<p>Output:</p>

<pre><code>matrix  sizes   solver  Compute Solve   Total   Rel Error   
small_SPD   5,5,8   Sparse LU AND COLAMD    8.9287e-05  1.0663e-05  9.995e-05   2.30263e-18 
small_SPD   5,5,8   BiCGSTAB    4.113e-06   1.853e-05   2.2643e-05  1.34364e-10 
</code></pre>

<p>Tab separated, which is probably useful for some applications - but you might want to <a href="http://perldoc.perl.org/functions/printf.html" rel="nofollow">printf</a> or <a href="http://perldoc.perl.org/functions/format.html" rel="nofollow">format</a> instead. </p>

python perl parsing