83464

Converting form layout to table (csv) layout in perl

Question:

I have an input file

<blockquote>

inputfile.txt

</blockquote> 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).

Answer1:

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.

<hr />

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.

Recommend

  • Global symbol requires explicit package [closed]
  • How could I write a Perl script to calculate the MD5 sum of every file in a directory? [closed]
  • my analysis of a Perl autovivification example
  • ssh2_scp_send() using php corrupts pdf
  • What to use (best/good practice) for the secret key in HMAC solution?
  • How to search for a record and then delete it
  • bcrypt-nodejs compare method returns false every time
  • Where does the file get saved using “File file = new file(filename)” in Android
  • How can I selectively modify the src attributes of script tags in an HTML document using Perl?
  • How to trick Node.js to load .js files as ES6 modules?
  • File loader changed image file name but not the file name in HTML file
  • Is there any way to call saveCurrentTurnWithMatchData without sending a push notification?
  • Angular Bootstrap Carousel Slide Transition not working correctly
  • SQL: Getting the physical size of a subset of a table
  • How do I remove all but some records based on a threshold?
  • How do I get the list of bad records that didn't load in Bigquery?
  • nodemcu custom firmware build problems
  • Android Studio Can't Find tools.jar
  • Convert SQLite database to XML
  • Redirect STDERR in OPEN pipe comand. Perl Linux
  • Silverlight DependencyProperty.SetCurrentValue Equivalent
  • Sequential (transactional) API calls in angular 4 with state management
  • Eclipse CDT error: Unable to compile
  • Rails Find when some params will be blank
  • MongoError: Incorrect arguments
  • How to create a file in java without a extension
  • Read a local file using javascript
  • How to redirect a user to a different server and include HTTP basic authentication credentials?
  • Can I make an Android app that runs a web view in Chrome 39?
  • Rearranging Cells in UITableView Bug & Saving Changes
  • Benchmarking RAM performance - UWP and C#
  • Angular 2 constructor injection vs direct access
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • LevelDB C iterator
  • Linking SubReports Without LinkChild/LinkMaster
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • UserPrincipal.Current returns apppool on IIS
  • java string with new operator and a literal
  • How to push additional view controllers onto NavigationController but keep the TabBar?