in reply to Parse a file and store it in hash of hashes

Hi. You are aware that perlmonks is neither a code writing service nor a job exchange, aren't you?

Show what you tried so far, and we'll help you with the remaining problems.

A great part of using perl is using CPAN. The file format looks very much like a Windows INI file, and that's a solved problem. Go to http://search.cpan.org and search for "INI". You will find many modules that can handle those files. Follow the links to the module documentation and find the one that fits best. Then open a command prompt, and type cpan install Your::Favorite::INI::Module.

If you insist on reinventing the wheel, but have no code yet, look up the documentation of strict, warnings, open, readline, split, autodie, and at least try to write a piece of code that reads the file line by line and splits the data line into key and value.

As with most other "simple" computer problems: Explain the problem in plain english, as you would for a very stupid human. As in: "Open the file foobar.ini. If that fails, stop. Else, read a line ...". From there, translating english to any computer language is quite easy.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^2: Parse a file and store it in hash of hashes
by Sonali (Novice) on Jan 16, 2017 at 08:24 UTC

    This is my code snippet. When i run this program there is no output at all. I am not able to figure out why

    #!/usr/local/bin/perl use strict; use warnings; use Data::Dumper; my $filename = 'tester.txt'; my %HoH; my $key; my $value; open(my $fh, '<:encoding(UTF-8)', $filename) or die "Could not open file '$filename' $!"; while ( <$fh> ) { next unless s/^\[(.*?)\]\s*//; $rec = $1; for my $field ( split /\n/) { ($key, $value) = split /\s*=\s*/, $field; $HoH{$rec}{$key} = $value; } } print Dumper %HoH;

      I find this highly unlikely. When I run your code, I get the following output:

      Global symbol "$rec" requires explicit package name at q:\tmp.pl line +12. Global symbol "$rec" requires explicit package name at q:\tmp.pl line +15. Execution of q:\tmp.pl aborted due to compilation errors.

      If I declare $rec as lexical variable and create an empty filename tester.txt, I get no output. This is because you're not using Data::Dumper properly

      print Dumper %HoH; # should be print Dumper \%HoH;

      Please post the actual code you are using.

      Also, look at Config::IniFiles, which does all of what you're doing already.

        That $rec was a typo. I have edited the code again. After I tried using Data::Dumper as you said I am getting the following output. I want to solve the problem using the HoH approach only so I have not used Config::Inifiles.

        $var1 = {};
      Hello Sonali and welcome to the monastery and to wonderful world of Perl!

      First of all follow the wise suggestions of the precise monk afoken.

      That said, with the code you posted, and in particular $rec = $1 I get the error Global symbol "$rec" requires explicit package name at pm16012017.pl line 12. but is probably a typo.

      In addition i think you just need a hash not a HashOfHash.

      Now about your code: if next unless s/^\[(.*?)\]\s*//; is intended to skip the first line must probably be: next if s/^\[(.*?)\]\s*//;

      Even with this you get errors about undefined values: Use of uninitialized value in hash element at inifile16012017.pl line 15, foreach line of data and the following datastructure:

      $VAR1 = ''; $VAR2 = { 'FIFTH' => '12345', 'COMMENT' => '"Perl parsing"', 'SEVENTH' => 'QWERTY', 'FOURTH' => '"RANDOM"', 'SECOND' => '"ID"', 'FIRST' => '"TEST"', 'THIRD' => '123', 'SIXTH' => '6789' };

      If you intended to have CELL_NAME as root element you need to not skip the line with it and have $rec declared outside the loop, to have it ad disposal during the loop:

      my $rec; while ( <$fh> ) { if (s/^\[(.*?)\]\s*//){$rec = $1}

      The resulting datastructure (dumped with Data::Dump with dd prettier method) will be:

      ( "CELL_NAME", { COMMENT => "\"Perl parsing\"", FIFTH => 12345, FIRST => "\"TEST\"", FOURTH => "\"RANDOM\"", SECOND => "\"ID\"", SEVENTH => "QWERTY", SIXTH => 6789, THIRD => 123, }, )

      L*

      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

        Yes you were correct about the typo at line 12. But I need HoH because my file is a collection of cell values like shown below. I had only posted one of the cells.

        [CELL_NAME1] COMMENT = "Perl parsing" FIRST = "TEST1" SECOND = "ID1" THIRD = 123 FOURTH = "RANDOM" FIFTH = 12345 SIXTH = 6789 SEVENTH = QWERTY [CELL_NAME2] COMMENT = "Tester" FIRST = "TEST2" SECOND = "ID2" THIRD = 1234 FOURTH = "FOUR" FIFTH = 12345 SIXTH = BOARD SEVENTH = MOUSE [CELL_NAME3] COMMENT = "Parser" FIRST = "TEST3" SECOND = "ID3" THIRD = 12345 FOURTH = "FIVE" FIFTH = 12345 SIXTH = PAD SEVENTH = KEY

        I need to generate a HoH structure for this.