in reply to Re^3: perl parsing
in thread perl parsing

Thank you for taking the time to assist me with this.I want to learn the HOH method, so I will try to use that in my solution with your aid.Using "print Dumper \%hash;" works and te HOH has all the info I need but I can't seem to print it out in a format I want . name device(s) <space> year My entire code is

#!/usr/bin/perl use strict; use Data::Dumper; my $infile = 'test_file.txt'; open (IN,'<',$infile) || die ("Could not open $infile : $!"); my $name; my %hash = (); while (<IN>){ s/^\s+|\s+$//g; # trim leading/trailing spaces my ($col1,$col2,$col3) = split /\s+/,$_,4; if ($col1 eq 'name'){ $name = $col2; } elsif ($col1 eq 'device') { push @{$hash{$name}},$col2,$col3; } else { # skip line } ## ## } close IN; #print Dumper \%hash; foreach my $line (keys %hash) { print "$line\n"; foreach my $sit (keys %{$hash{$line}}) { print "$hash{$line}{$sit}\t$sit"; } }

DATA

name Brian device Ipad 2001 device iphone 2000 number 2 name Jason device computer 2011 number 1 name Andrew device ipad 1999 device iphone 1990

Replies are listed 'Best First'.
Re^5: perl parsing
by poj (Abbot) on Oct 06, 2017 at 16:59 UTC

    Change this line to build a Hash of Arrays (HoA)

    #push @{$hash{$name}},$col2,$col3; push @{$hash{$name}},"$col2\t$col3"; # device year

    and change the output loop to

    foreach my $name (keys %hash){ print "$name\n"; foreach my $sit (@{$hash{$name}}){ print "\t$sit\n"; } }
    poj

      Thank you poj!!! .Can you help me understand please, how would I know not to use foreach my $sit (keys %{$hash{$line}}) when tutorials are saying I was to do it that way, but to use foreach my $sit (@{$hash{$name}}).

      Why did I need to \t when creating the hoh and not use ,<comma> when Dumper had the correct info just couldnt print it out

      #push @{$hash{$name}},$col2,$col3; push @{$hash{$name}},"$col2\t$col3"; # device year

      2017-10-08 Athanasius added code tags

        Dumper had the correct info

        If your output was like this

        $VAR1 = { 'ryan' => [ 'ipad', '2005', 'cell', '2009' ], 'Brian' => [ 'ipad', '2001', 'ipad', '2001', 'ipad', '2001' ], 'Andrew' => [ 'ipad', '2009' ] };

        that is not a HashOfHashes, it is a HashOfArrays. push @{$hash{$name}},$col2,$col3 is creating 2 array element for each line of data

        push @{$hash{$name}},"$col2,$col3" creates only 1 array element for each line. see push

        A HashOfHashes (HoH) would be used if you wanted to replace multiple records the same with 1 record and a count, like this

        while (<IN>){ s/^\s+|\s+$//g; # trim leading/trailing spaces my ($col1,$col2,$col3) = split /\s+/,$_,4; if ($col1 eq 'name'){ $name = $col2; } elsif ($col1 eq 'device') { #push @{$hash{$name}},"$col2\t$col3"; ++$hash{$name}{$col2}{$col3}; #HoH } else { # skip line } } close IN; foreach my $name (keys %hash){ print "$name\n"; foreach my $col2 (keys %{$hash{$name}}){ foreach my $col3 (keys %{$hash{$name}{$col2}}){ my $count = $hash{$name}{$col2}{$col3}; print "\t$col2\t$col3\t$count\n"; } } }
        poj