0

I have an input file

inputfile.txt

        name: George
         age: 5
      nature: curious
       likes: banana

This is what I call a form layout. I am trying to convert this in to a table layout, CSV. For instance:

name,age,nature,likes
George,5,curious,banana

So, I read the file, split on ": and \n" and place values in to a hash. Then push that hash in to an array so I can take them out later. Here is what I have done so far.

#!/usr/bin/perl
use strict;

 open (MYFILE, 'inputfile.txt');
 my @records;
 while (<MYFILE>) {
        chomp;
        my %values = split(/[:\n]/,$_);
        push @records,%values;
 }
 close (MYFILE);

By this, I guess @records={[name=George],[age=5],[nature=curious],[likes=banana]} would have happened.

Now, how do I get each hash out of the array @records? when I try something like:

 foreach my $record(@records){
     my %record = $record;
     for my $key(keys %record){
        print "key : $key\n";
     }
 }

It outputs all tokens one after other unlike what is expected (just the key).

1 Answer 1

5

I would do it in a slightly different way...

my (@values, @properties);
while (<DATA>) {
  if (/(\S*)\s*:\s*(\S*)/) {
    push @values, $1;
    push @properties, $2;
  }
}
print join ',', @values;
print "\n";
print join ',', @properties;
print "\n";
__DATA__
        name: George
         age: 5
      nature: curious
       likes: banana

... for two reasons.

First, a hash in Perl is unordered, and there's no easy way to sort these properties back to their original state. In these cases, using arrays is preferable.

Second, using regex match instead of split allows to deal with bad data easier (in this code, the pattern is quite simple, but it's quite easy to get validation logic there). Besides, all the chunks of data are captured immediately; you don't need to chomp or transform them additionally.


And speaking of your original code: this line...

push @records, %values;

... had to be rewritten into ...

push @records, \%values;

... to mean anything usable. Remember, arrays are flattened in Perl, and when you try to push a hash into array, it'll just be transformed into a list (and then this list will get appended to that array).

Still, when you have to output such an array of hashes, you have to go through keys of its elements, then go through values of its elements: it's not necessary, if you just store these separately, as in my code.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.