http://www.perlmonks.org?node_id=1009486

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

I for the life of me cannot find a useful example for my needs. I am looking for a simple example of parsing a text file and creating a CSV file. For example something that converts this text file:

Line1info Line2someMoreInfo Line3 more info Line5line4IsBlank Line6isTabbed Line7isToo Line8hasMoreStuff

into this CSV file:

Line1, Line3, Line6, Line7 Line1info, Line3 more info, Line6isTabbed, Line7isToo

I figured this would be a common request but apparently I was wrong. Every example I've found does not fit the bill. If someone could point me to an example that I could use as a template to learn from that would be great. If it is easy to produce an example from the generic data I provided that would be great too.

Just in case being more specific is helpful, here is exactly what I'm trying to do

Flat File

NetDevice1234 Kernel: Linux 2.6.18-164.11 Version: Driver 23.4.1 333.0 Hotfix BLD Edition Hot fixes: HF372590 HF372804 HF372864 Enabled Features: FTP HTTP SMTP Active Directory

Into a CVS with the following contents:

Host, OS, Version, Hot Fixes, Features NetDevice1234, Linux 2.6.18-164.11, Driver 23.4.1 333.0 Hotfix BLD Edi +tion, HF372590 HF372804 HF372864, FTP HTTP SMTP Active Directory

Thanks for any help you can provide everyone!

Replies are listed 'Best First'.
Re: Simple parse of text file to csv
by 2teez (Vicar) on Dec 19, 2012 at 06:06 UTC

    "..parsing a text file and creating a CSV file.."

    of course, if you are creating a CSV file, you will have to look into module Text::CSV or Text::CSV_XS. Hence, davido's important comment.
    However, for "Flat File", data you posted the following should still work:

    use warnings; use strict; my %data_config; my $key; while (<DATA>) { chomp; if (/(.+?):$/) { $key = $1; } else { push @{ $data_config{$key} }, $_; # {updated} } } print "Host, OS, Version, Hot Fixes, Features\n"; for ( 'Host', 'Kernel', 'Version', 'Hot fixes', 'Enabled Features' ) { print "@{$data_config{$_}}, "; } __DATA__ Host: NetDevice1234 Kernel: Linux 2.6.18-164.11 Version: Driver 23.4.1 333.0 Hotfix BLD Edition Hot fixes: HF372590 HF372804 HF372864 Enabled Features: FTP HTTP SMTP Active Directory
    Output:
    Host, OS, Version, Hot Fixes, Features NetDevice1234, Linux 2.6.18-164.11, Driver 23.4.1 333.0 Hotfix BLD Edi +tion , HF372590 HF372804 HF372864, FTP HTTP SMTP Active Dir +ectory,

    Update:
    Thanks Tux, $key was intended, instead of $1 used in this line push .... It has been corrected.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me

      $1 in the push should have been $key. Translated to Text::CSV_XS

      use strict; use warnings; use Text::CSV_XS; my %values; my $key; my @keys; while (<DATA>) { chomp; m/^\s*#/ and next; # Skip comment m/^\s*$/ and next; # Skip empty lines if (m/^\s* (.+?) \s*:\s* $/x) { $key = $1; push @keys, $key; next; } s/^\s+//; s/\s+$//; push @{ $values{$key} }, $_; } my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1, eol => "\n +" }); $csv->print (*STDOUT, \@keys); $csv->print (*STDOUT, [ map { "@$_" } @values{@keys} ]);

      With the __DATA__ section added, results in:

      Host,Kernel,Version,"Hot fixes","Enabled Features" NetDevice1234,"Linux 2.6.18-164.11","Driver 23.4.1 333.0 Hotfix BLD Ed +ition","HF372590 HF372804 HF372864","FTP HTTP SMTP Active Directory"


      Enjoy, Have FUN! H.Merijn
Re: Simple parse of text file to csv
by davido (Cardinal) on Dec 19, 2012 at 04:21 UTC

    This seems pretty straight-forward, but I'm not seeing any mention of what constitutes a record separator. I would want to nail that down before proceeding.


    Dave

Re: Simple parse of text file to csv
by rpnoble419 (Pilgrim) on Dec 19, 2012 at 04:23 UTC
    or is the data a fixed length record?