use warnings; use strict; use Data::Dump::Streamer; my @libs; local $/ = 'libname='; # Read a record at a time while () { chomp; next if ! length; # Skip blank lines s/\n|\r/ /g; # Remove conventional line end characters next if ! s/(\S+)\s*//; my $str = $_; my %record; $record{libname} = $1; while ($str =~ /=/) { # Process an option last if ! ($str =~ s/\s*(\S+?)\s*=\s*//); my $opName = $1; my $opValue; if ($str =~ s/^\s*"([^"]*)"\s*//) { # Complicated option value $opValue = parseSubOps ($1); } elsif ($str =~ s/\s*(\S+)\s*//) { # Simple option $opValue = $1; } $record{$opName} = $opValue; } push @libs, {%record}; } Dump (\@libs); sub parseSubOps { my $str = shift; my %subOps; while ($str =~ /=/) { # Process a sub-option last if ! ($str =~ s/\s*(\S+)\s* = \s*\(\s* ([^)]*?) \)\s*//x); my $name = $1; my @values = $2 =~ /'([^']*?)'/g; $subOps{$name} = \@values; } return \%subOps; } __DATA__ libname=foo pathname=/path/to/metadata/foo owner=someuser libaclinherit=no dynlock=no roptions=" datapath=('/data/path1' '/data/path2' '/data/path3' ...) indexpath=('/indx/path1' '/indx/path2' '/indx/path3' ...) workpath=('/work/path1' '/work/path2' '/work/path3' ...) metapath=('/meta/path1' '/meta/path2' '/meta/path3' ...)"; libname=bar pathname=/path/to/metadata/bar owner=someuser libaclinherit=no dynlock=no roptions=" datapath=('/data/path1' '/data/path2' '/data/path3' ...) indexpath=('/indx/path1' '/indx/path2' '/indx/path3' ...) workpath=('/work/path1' '/work/path2' '/work/path3' ...) metapath=('/meta/path1' '/meta/path2' '/meta/path3' ...)"; libname=foobar pathname=/path/to/metadata; #### $ARRAY1 = [ { dynlock => 'no', libaclinherit => 'no', libname => 'foo', owner => 'someuser', pathname => '/path/to/metadata/foo', roptions => { datapath => [ '/data/path1', '/data/path2', '/data/path3' ], indexpath => [ '/indx/path1', '/indx/path2', '/indx/path3' ], metapath => [ '/meta/path1', '/meta/path2', '/meta/path3' ], workpath => [ '/work/path1', '/work/path2', '/work/path3' ] } }, { dynlock => 'no', libaclinherit => 'no', libname => 'bar', owner => 'someuser', pathname => '/path/to/metadata/bar', roptions => { datapath => [ '/data/path1', '/data/path2', '/data/path3' ], indexpath => [ '/indx/path1', '/indx/path2', '/indx/path3' ], metapath => [ '/meta/path1', '/meta/path2', '/meta/path3' ], workpath => [ '/work/path1', '/work/path2', '/work/path3' ] } }, { libname => 'foobar', pathname => '/path/to/metadata;' } ];