Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

How to print a string in a specific format when parsing a complex data structure

by newperluser2013 (Novice)
on May 07, 2013 at 02:54 UTC ( #1032429=perlquestion: print w/replies, xml ) Need Help??
newperluser2013 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl monks I have a problem that I can't seem to get working and I was hoping you could help me please. I have a subrountine which I am using to parse a complex data structure and as I go through all the nested hashes I am looking for a list of certain keys and once I have all of these keys I am printing a line of output for each time I find a full set of keys. I am storing the list of keys in @keys_to_find and this looks like this:

%volume %mnt %device %perms %user %mntops %other

The subroutine I am using to parse the complex data structure and pass in @keys_to_find looks like this. This is able to correctly parse the data structure and print out individual lines containing all the values of each one of the keys in @keys_to_find.

sub traverse_hash { my ($jsonhash, $found, @keys_to_find) = @_; my $results = 'results.txt'; open(FILE, ">>$results"); for my $key (sort keys %{$jsonhash}) { my $keyvalue = $jsonhash->{$key}; if ('HASH' eq ref $keyvalue) { $found = {%$found, %{ traverse_hash($keyvalue, $found, @ke +ys_to_find) }}; } for my $find (@keys_to_find) { if ($key eq $find) { if ('HASH' eq ref $keyvalue) { $found->{$key} = [ map $keyvalue->{$_}, sort keys +%$keyvalue ]; } else { $found->{$key} = $keyvalue; } } } } if (@keys_to_find == keys %$found) { my $count; $count = @{ (grep 'ARRAY' eq ref $_, values %$found)[0] // [] +}; $count ||= 1; for my $i (0 .. $count - 1) { print FILE join(':', map { 'ARRAY' eq ref $_ ? $_->[$i] : +$_ } @{$found}{@keys_to_find}), "\n"; } $found = {}; } return $found; close(FILE); }

What I am struggling to work out how to do is to additionally pass into this subroutine an output format string so I can print the results in different formats rather than print lines containing every value for all the keys in @keys_to_find. So for example I want to pass in a a variable which contains an output format string like so:

$output_format = '%mnt:%device:%volume:%perms';

So with this $output_format string I want to be able to call the subroutine like this:

traverse_hash(\%$decoded_json_obj, {}, @keys_to_find, $output_format);

So when this subroutine is called like above I want it first to make sure that every key in @keys_to_find exists at each level in data structure (like it currently does) and then if all those keys exist then print out a line/s of output in the format of whatever keys are defined in $output_format string variable. The contents of $output_format will be different each time I call this subroutine so I can't pass into this subroutine a hardcoded string. I need to pass this in as a variable. Please can you help me with how to do this?

Replies are listed 'Best First'.
Re: How to print a string in a specific format when parsing a complex data structure
by LanX (Bishop) on May 07, 2013 at 03:25 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1032429]
Approved by BrowserUk
and the shadows deepen...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2018-01-19 15:52 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (221 votes). Check out past polls.