问题
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