#!/usr/bin/perl use warnings; use strict; use v5.14; # Hashrefs for keys and values. use JSON; use Data::Dumper; sub recurse_hash { my ($hash, $found, @findkeys) = @_; for my $key (sort { # Defaults go first. local $a = q() if '%default' eq $a; local $b = q() if '%default' eq $b; $a cmp $b; } keys %{$hash}) { my $value = $hash->{$key}; if ('HASH' eq ref $value) { $found = {%$found, %{ recurse_hash($value, $found, @findkeys) }}; } for my $find (@findkeys) { if ($key eq $find) { if ('HASH' eq ref $value) { $found->{$key} = [ map $value->{$_}, sort keys $value ]; } else { $found->{$key} = $value; } } } } if (@findkeys == keys $found) { my $count; $count = @{ (grep 'ARRAY' eq ref $_, values $found)[0] // [] }; $count ||= 1; for my $i (0 .. $count - 1) { print join(':', map { 'ARRAY' eq ref $_ ? $_->[$i] : $_ } @{$found}{@findkeys}), "\n"; } print "\n"; $found = {}; } return $found; } my @keylist = qw(%export_name %filer_device %filer_volume %mount_acl %mount_group %mount_user %mount_opts); my $string = do { local $/; }; my $struct = decode_json($string); recurse_hash($struct, {}, @keylist); __DATA__ { "%name": "Global Central Configuration file", "%description": "A representation of nfs mount points for dev machines", "%schema": "schema.conf", "@dev": { "home_nfs": { "%default": { "%mount_opts": "nfsvers=3,timeo=600,retrans=2", "%mount_user": "root", "%mount_group": "root", "%mount_acl": "0755" }, "%comment": "----Home NFS Directories----", "home-lnk-mpt": { "%export_name": "/links", "%filer_device": { "@west": "nydevnfs_links", "@ridge": "rnap7750-s" }, "%filer_volume": { "@west": "/vol/links", "@ridge": "/vol/links_c" } }, "home7_mpt": { "%export_name": "/home7", "%filer_device": { "@west": "nydevnfs_home7", "@ridge": "rnap7751-s" }, "%filer_volume": { "@west": "/vol/home7", "@ridge": "/vol/home7_c" } }, "home8_mpt": { "%export_name": "/home8", "%filer_device": { "@west": "nydevnfs_home2", "@ridge": "rnap2114-s" }, "%filer_volume": { "@west": "/vol/home2", "@ridge": "/vol/home2_c" } } } } }