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

Hi,

I am trying to parse a delimited file and based on certain
logic creating separate files.
Here's content of a sample file with '^' as the separator -

1^InformationCompanyConsumerUpdateFile^4457^1/07/2002^14:35
2^1^john.doe@imail.com^1234^20020102
3^1^^Johnathon^Doe^^8^
4^1^1^123 Happy Trail Drive^^Tuscon^AZ^44587^1487
8^1^BU1534567^12345^01119
2^2^Fanklin.Roosevelt@whitehouse.com^1234^20020105
3^2^^Franklin^Roosevelt^^8^
4^2^1^55 Congress Drive^^Washington^DC^11265^
8^2^BU1234567^12345^01119
2^3^lincoln@log.com^1234^20020101
4^3^1^99 Honest ^^Chicago^IL^58302^
8^3^BU222234^ 01595^01119|011124
8^3^BU222234^ 02516^Y
8^3^BU222234^ 01616^2

The second value like 1, 2, 3 ... are the unique ids for
the records of a particular individual.
The first column value is the record type.
For example 1 is for the header information, 2 for the email
information etc., 3 is for the individual's first, middle,
last name etc., 8 is for the questionaire answers.
. Based on the unique id (key) as mentioned above
I need to create 3 separate pipe delimited files like as below -

Header file (for first column value of '1') -

InformationCompanyConsumerUpdateFile|4457|1/07/2002|14:35

Data file (for first column values of '3,4 and 2' in sequence)-

1||Johnathon|Doe||8|123 Happy Trail Drive||Tuscon|AZ|44587|1487|john.doe@imail.com|1234|20020102

Questionaire file (for first column value of '8') -

1|BU1534567|12345|01119

I hope I have stated my problem clearly.
Would appreciate if I could find the best possible solution
for this problem.<pr> Thanks

  • Comment on Parsing a file and splitting into multiple files

Replies are listed 'Best First'.
Re: Parsing a file and splitting into multiple files
by jwkrahn (Abbot) on Sep 12, 2006 at 22:45 UTC
    This appears to do what you want:
    #!/usr/bin/perl use warnings; use strict; open my $F, '<', 'file' or die "Cannot open 'file' $!"; open my $H, '>', 'header' or die "Cannot open 'header' $!"; open my $D, '>', 'data' or die "Cannot open 'data' $!"; open my $Q, '>', 'questionaire' or die "Cannot open 'questionaire' $!" +; my %data; while ( <$F> ) { chomp; my ( $type, @fields ) = split /\^/, $_, -1 or next; if ( $type == 1 || $type == 8 ) { print { $type == 1 ? $H : $Q } join( '|', @fields ), "\n"; } elsif ( $type == 2 || $type == 3 || $type == 4 ) { $data{ $fields[ 0 ] }[ $type % 3 ] = [ @fields[ 1 .. $#fields +] ]; } if ( ( eof && %data ) || %data && $type != 2 && $type != 3 && $typ +e != 4 ) { my ( $key, $val ) = %data; print $D join( '|', $key, map defined() ? @$_ : (), @$val ), " +\n"; %data = (); } }
Re: Parsing a file and splitting into multiple files
by shmem (Chancellor) on Sep 12, 2006 at 17:33 UTC
    Have you read How do I post a question effectively? If not, do so, please.

    Your solution first; then we could hack on that. C'mon, show some effort.
    <update> Remember this post?</update>

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Parsing a file and splitting into multiple files
by ysth (Canon) on Sep 12, 2006 at 17:30 UTC
    Can you show what you've tried? Or explain what problem you are having? (Ideally, both.)
Re: Parsing a file and splitting into multiple files
by runrig (Abbot) on Sep 12, 2006 at 17:58 UTC
    Here's an awk solution to get you started (though it writes every input record to a separate output record, and I think you said you wanted to put the 2,3,4 records on the same line):
    #!/usr/bin/awk -f { gsub(/\^/, "|") } /^1/ { print >> "header.txt" } /^[234]/ { print >> "data.txt" } /^8/ { print >> "questions.txt" }
    run a2p to convert this to perl.