in reply to creating the hierarchy pattern from the input file

Well, here's a best guess...

#!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11136806 use warnings; my %hash; while( <DATA> ) { chomp; my $code = s/\@/}{/gr; eval "\$hash{$code}++"; } #use Data::Dump 'dd'; dd \%hash; sub nest { my $h = shift; my $answer = ''; if( ref $h ) { for my $k ( sort keys %$h ) { $answer .= ref( $h->{$k} ) ? "$k {\n" . nest( $h->{$k} ) =~ s/^/\t/gmr . "}\n" : $k . "\n"; } } $answer; } local $_ = nest \%hash; s/\w\K\n\s*(?=\w)/,/g; print; __DATA__ instreg@d1@d1 instreg@d1@d2 instreg@d2@d1 instreg@d3@d1 instreg@d4@d1 instreg@d5@d1 instreg@d6@d1 instreg@d7@d1 instreg@d8@d1 alureg@d1@d1 alureg@d2@d1 alureg@d3@d1 alureg@d4@d1 alureg@d5@d1 alureg@d6@d1 alureg@d7@d1 alureg@d8@d1 pgmctr@d1@d1 pgmctr@d2@d1 pgmctr@d3@d1 pgmctr@d4@d1 pgmctr@d5@d1 pgmctr@m1 pgmctr@m2 pgmctr@m3 pgmctr@m4 pgmctr@m5

Outputs:

alureg { d1 { d1 } d2 { d1 } d3 { d1 } d4 { d1 } d5 { d1 } d6 { d1 } d7 { d1 } d8 { d1 } } instreg { d1 { d1,d2 } d2 { d1 } d3 { d1 } d4 { d1 } d5 { d1 } d6 { d1 } d7 { d1 } d8 { d1 } } pgmctr { d1 { d1 } d2 { d1 } d3 { d1 } d4 { d1 } d5 { d1 } m1,m2,m3,m4,m5 }

If this is not what you are looking for, please show the exact output you want, especially for pgmctr, which as LanX has pointed out, has an array/hash conflict.

P.S. This is also sure to upset the 'eval' haters :)

Replies are listed 'Best First'.
Re^2: creating the hierarchy pattern from the input file
by LanX (Saint) on Sep 16, 2021 at 10:47 UTC
    > P.S. This is also sure to upset the eval haters :)

    Trouble is rather that you might end with a bug depending on input if you try increment a hashref.

    I would prefer

    DB<41> $ref= $tree DB<42> x @keys = split /@/,'a@b@c' 0 'a' 1 'b' 2 'c' DB<43> $ref = ($ref->{$_}//={})for @keys DB<44> x $tree 0 HASH(0xaa630cf0) 'a' => HASH(0xaa6204a0) 'b' => HASH(0xaa6719b0) 'c' => HASH(0xaa75baa0) empty hash DB<45>

    Update
    And so on for each line
    DB<45> x @keys = split /@/,'a@b@d' 0 'a' 1 'b' 2 'd' DB<46> $ref= $tree <= ($ref->{$_}//={})for @keys DB<48> x $tree 0 HASH(0xaa630cf0) 'a' => HASH(0xaa6204a0) 'b' => HASH(0xaa6719b0) 'c' => HASH(0xaa75baa0) empty hash 'd' => HASH(0xaa672e30) empty hash DB<49>

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re^2: creating the hierarchy pattern from the input file
by LanX (Saint) on Sep 16, 2021 at 11:09 UTC
    I'm not an eval hater but this is prone to injections.

    (OTOH is vulnerable code maybe the best solution for people abusing the monastery as code writing service. ;)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      > maybe the best solution for people abusing the monastery as code writing service ;)

      Yes, this seems to be getting worse lately!

      I'm reminded of Ian Phillipps' little perl program-generator of 1990. All it did was ask you to enter the program you wanted written ... then post to comp.lang.perl with a title of "I don't think perl can $program_you_wanted_written". In those days, there were plenty of Perl zealots eager to prove that Perl could indeed do it! :) (Mentioned at The Lighter Side of Perl Culture (Part I): Introduction).

        > Yes, this seems to be getting worse lately!

        not sure about that, I think in absolute numbers it's still the same person(s) creating sockpuppets.

        It's just that the serious questions are getting relatively rare.

        Not sure how much the competition by SO and Reddit matters.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Re^2: creating the hierarchy pattern from the input file
by Anonymous Monk on Sep 17, 2021 at 08:22 UTC

    P.S. This is also sure to upset the 'eval' haters :)

    Data::Diver

Re^2: creating the hierarchy pattern from the input file
by pruthvik (Initiate) on Sep 16, 2021 at 10:26 UTC

    Yes this is the expected output , can you also suggest as if the input was a part of a file where to pass the file handle for further processing

    Thanks

      Here's an updated version using ideas stolen borrowed from LanX.

      It sounds like the provided input might be a section of a larger file. If so, you could either pass in the section as a string and use the reference open as shown, or pass in the file handle ($fh) and also specify some input line that will cause a return to caller.

      #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11136806 use warnings; my $inplacefile = <<'END'; instreg@d1@d1 instreg@d1@d2 instreg@d2@d1 instreg@d3@d1 instreg@d4@d1 instreg@d5@d1 instreg@d6@d1 instreg@d7@d1 instreg@d8@d1 alureg@d1@d1 alureg@d2@d1 alureg@d3@d1 alureg@d4@d1 alureg@d5@d1 alureg@d6@d1 alureg@d7@d1 alureg@d8@d1 pgmctr@d1@d1 pgmctr@d2@d1 pgmctr@d3@d1 pgmctr@d4@d1 pgmctr@d5@d1 pgmctr@m1 pgmctr@m2 pgmctr@m3 pgmctr@m4 pgmctr@m5 END my $filename = \$inplacefile; # FIXME change to filename with no refer +ence open my $fh, '<', $filename or die $!; # FIXME improve error message my $hash = {}; while( <$fh> ) { my $ref = $hash; $ref = $ref->{$_} //= {} for split /\@|\n/; } #use Data::Dump 'dd'; dd $hash; sub nest { my $h = shift; join '', map { %{$h->{$_}} ? "$_ {\n" . nest( $h->{$_} ) =~ s/^/\t/gmr . "}\n" : +"$_\n"; } sort keys %$h; } print nest($hash) =~ s/\w\K\n\s*(?=\w+$)/,/gmr;

      Same output as before.

      atta man! that's how you advance the state-of-the-art!