#!/usr/bin/perl use warnings; use strict; use Test::More tests => 1; my $input = 'A | |--B | | | |--C | | | |---PQR | |---XYZ |--D | | | |---LMN |---XYZ '; open my $IN, '<', \$input or die $!; my @path; my @output; my $size = 0; while (<$IN>) { if (!/\|/) { # Root. @path = [0, /(\S+)/]; } elsif (/\|(?=-)/g) { # Capture the position of the last |. if ($path[-1][0] == pos) { # Sibling. ($path[-1][1]) = /-+(\S+)/; } elsif ( $path[-1][0] < pos) { # Child. push @path, [pos, /-+(\S+)/]; } else { # New branch. pop @path until $path[-1][0] == pos; $path[-1] = [pos, /-+(\S+)/]; } if (/---/) { push @output, [ map $_->[1], @path ]; $size = @path if @path > $size; } } } my $expected = 'Coloum1 Coloum2 Coloum3 Coloum4 A B C PQR A B C XYZ A D LMN A XYZ '; my $output = join "\t", map "Coloum$_", 1 .. $size; for my $row (@output) { $output .= "\n"; $output .= join "\t", @{$row}[0 .. $#{$row} - 1], (q()) x ($size - @$row), $row->[-1]; } $output .= "\n"; is($output, $expected);