s_gaurav1091 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have a doubt that how can i read a file and parse the values and create a hash out of it. for example a file contains a line maintenance_mode ServiceMonitor,name=BoyScoutService now i want my hash to contain a key of maintenance_mode and a value ServiceMonitor,name=BoyScoutService

Replies are listed 'Best First'.
Re: create a hash by reading file
by Nevtlathiel (Friar) on Jul 19, 2005 at 11:17 UTC
    You're going to have to be more specific about how to tell the key from the value in your file? Are they just seperated by whitespace? The following (which is entirely UNTESTED) will match 'maintenance_mode' followed by whitespace followed by any number of word characters, commas or equals signs, but you'll need to look at the data in your file to work out a better regex.

    #! /usr/bin/perl use strict; use warnings; unless ( open( FILE, "name_of_file" ) ) { die "Could not open file for reading\n"; } my %hash; while (<FILE>) { if ($_ =~ /^(maintenance_mode)\s([\w,=]*)$/) { $hash{$1} = $2; } }

    ----------
    My cow-orkers were talking in punctuation the other day. What disturbed me most was that I understood it.

      I'm guessing that the OP will want more than one key in his hash and therefore that the key names will exhibit a little more variety :)

      #!/usr/bin/perl use strict; use warnings; open FILE, 'name_of_file' or die "Could not name_of_file for reading: $!\n"; my %hash; while (<FILE>) { if (/^(\w+)\s+([\w,=]*)$/) { $hash{$1} = $2; } }
      --
      <http://www.dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

      You're going to have to be more specific about how to tell the key from the value in your file? Are they just seperated by whitespace?
      Although his post was poorly formatted I think that they're separated by comma. But then there's no indication whatsoever whether there may be commas in the key and/or in the value respectively -suitably quoted, of course-, in which case Text::CSV_XS may be the best option.
      unless ( open( FILE, "name_of_file" ) ) { die "Could not open file for reading\n"; }
      Well, nothing to say about this, but the "open or die" idiom is so typically perlish that it seems strange to see anything different...

      As a possibly minor point, I always prefer the three args form of open and I prefer to use "lexical filehandles". I have to say that wrt this issue Abigail himself in clpmisc once supplied good arguments in favour of the two-args form. But as general rule my indications should be preferable in most situations, with modern enough perls.

      Also, it is generally recommended, and is indeed sentible, to include $! in the error message.

      while (<FILE>) { if ($_ =~ /^(maintenance_mode)\s([\w,=]*)$/) {
      You see, $_ is the "topicalizer". Its whole point (well, not the whole point, but a good portion of it) is that it is the implicit argument of many "actions". So
      $var =~ /whatever/;
      is OK, but
      $_ =~ /whatever/;
      is plainly equivalent to
      /whatever/;
      with the only difference that the latter is clearer. Well, to a perl programmer, of course! Occasionally people even uses a for for its aliasing properties only, e.g.:
      for ($foo) { s/^"//; s/"$//; s/\W+/-/; } # or also: # s/^"//, s/"$//, s/\W+/-/ for $foo;
      BTW: your regexp will only match one key, so that I wouldn't regard it as especially useful for filling a hash;
      $hash{$1} = $2; } }

      Also, what you did is certainly legitimate, but since here we're talking about breaking a string in two parts, perhaps split could have been better suited for the job. This, of course, modulo the caveat I already took care of above. En passant it occurs to me that it may be worth to remind you of the LIMIT parameter of split, that is not that known after all...

      PS: for such minimal examples (and for much more) IMHO the ARGV filehandle is invaluable. See also the discussion going on at How would you do it? Re ARGV, fundamentally!, and especially merlyn's answer

Re: create a hash by reading file
by reasonablekeith (Deacon) on Jul 19, 2005 at 11:20 UTC
    How far have you got? Are you having trouble...

    opening the file?
    reading the file?
    parsing the data?
    building the hash?
    ---
    my name's not Keith, and I'm not reasonable.
      hi I have got the result and your guess was perfectly ok.My file contained lines separated by spaces.Thanks alot for the answer