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

I have a file that contains multiple lines such as -
123456,12/01/2004,ABCDEFG,12345 ,XYZ

What would be the best way to convert this comma delimited file
into a fixed length one?

Comment on convert a comma delimited file to a fixed length
Re: convert a comma delimited file to a fixed length
by ww (Bishop) on Nov 04, 2005 at 14:15 UTC
    you'll usually get better replies if you show what you've tried (with code).

    Otherwise, you are, in effect, asking "please do this for me, for free, instead of your own work."

    In fact, in this case, and being highly charitable about it, the "please" is only implicit!

    for a hint, though...
    • what's your longest field?;
    • what perl operator could you use to pad those fields shorter than the longest to the length of the longest?
    • and what would you still have left to do at that point?

    Update: The last above is based on a guess that you want to create is classic "fixed length fields" -- where each field of each record is the same length, enabling use of pos to determine where one field ends and another begins. This, of course, may not be your intent... but if so refer to other's replies re ambiguity of your question, and to How do I post a question effectively?.

Re: convert a comma delimited file to a fixed length
by Perl Mouse (Chaplain) on Nov 04, 2005 at 14:17 UTC
    Could you be more specific? What do you mean by a "fixed length file"? Do you mean fixed length records perhaps? The question then is, how long should the records be? People tend to use comma delimited values over fixed length records because not all their records are fixed length.
    s/.*/ /
    will replace your lines with fixed length ones - but I doubt that is what you want.
    Perl --((8:>*
Re: convert a comma delimited file to a fixed length
by blue_cowdawg (Monsignor) on Nov 04, 2005 at 14:24 UTC
        What would be the best way to convert this comma delimited file into a fixed length one?

    I'm not 100% sure, but is this what you are after?

    #!/usr/bin/perl -w use strict; while (my $line=<DATA>) { chomp $line; my @f=split(",",$line); my $fmt = sprintf("%s","%10s" x 5) . "\n"; printf $fmt,@f; } __END__ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ 123456,12/01/2004,ABCDEFG,12345 ,XYZ

    When that code is run you get:

    12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ 12345612/01/2004 ABCDEFG 12345 XYZ

    Not sure what you mean by "fixed length" or what your criteria for the proper field width is, but the principle remains the same.

    In future you'd get better responses if you are more specific about what your requirements are.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: convert a comma delimited file to a fixed length
by BrowserUk (Pope) on Nov 04, 2005 at 14:25 UTC

    There are many forms of "fixed length records". Binary, ascii,, mixed. But assuming you just want to space out the fields to fixed widths, you need to make two passes.

    The first finds the maximum lengths of each field, by splitting using split or one of the csv modules as appropriate, and using length (and List::Util::max).

    The second uses the maximum field widths from the first pass to format the data for output using either printf or pack.

    You'll then need to decide whether each field should be left or right justified and what your overall record length should be and so on. And most of that will depend upon what you intend to do with the fixed width record file afterwards. Is it intended for use by another application? If so, what are the formatting requirements of that application?

    There is enough there to get you started, but a clearer picture of what you are trying to do would help a lot.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: convert a comma delimited file to a fixed length
by radiantmatrix (Parson) on Nov 04, 2005 at 14:32 UTC

    I see many people suggesting a split and feeding the results through printf or sprintf to pad them to an appropriate length. While that works for the sample data above, I highly recommend using Text::CSV_XS to parse the comma-delimited file, because it will let you deal with more complex cases (and might actually be faster due to the XS code).

    Also, while the printf family of functions works fine for this, isn't this particular application almost exactly what format and write were made for? Read perlform for more about using formatting to write out records.

    <-radiant.matrix->
    A collection of thoughts and links from the minds of geeks
    The Code that can be seen is not the true Code
    "In any sufficiently large group of people, most are idiots" - Kaa's Law
Re: convert a comma delimited file to a fixed length
by jZed (Prior) on Nov 04, 2005 at 14:36 UTC
    The DBD::AnyData module handles both CSV and Fixed Length formats. Here would be the entire script to convert from one to the other:
    #!/usr/bin/perl -w use strict; use DBI; my $pattern = {pattern=>'A6 A9 A8 A5 A3'}; # widths of cols my $dbh=DBI->connect('dbi:AnyData(RaiseError=1):'); $dbh->ad_catalog('T1','CSV','yourfile.csv'); $dbh->ad_catalog('T2','Fixed','yourfile.fix',$pattern); $dbh->do("CREATE TABLE T2 AS SELECT * FROM T1"); __END__
    If you don't like SQL, the AnyData module will let you do the same thing with a tied-hash interface.
Re: convert a comma delimited file to a fixed length
by davidrw (Prior) on Nov 04, 2005 at 15:06 UTC
    The module solutions above will be the most robust .. Just wanted to throw one more into the mix for the sake of TMTOWTDI:
    perl -pe 's/([^,]*),/ $1 . " "x(10-length($1))/eg' foo.txt