Converting form layout to table (csv) layout in perl

心不动则不痛 提交于 2019-12-13 04:28:36

问题


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:


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.



来源:https://stackoverflow.com/questions/12606045/converting-form-layout-to-table-csv-layout-in-perl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!