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

Hi Folks

Please bare with me, it has been years and years since I have even SEEN perl and was thrilled this site was still around. Never being a hot-shot programmer in the first place, I am in need of some help. Looking over some old code it was asked if a FF could be sorted alphabetically. Of course I know I could use sort for this but when I wrote this pre 2000 sometime I have a flat file with the first two elements displayed and a button to view the whole "line" in the flatfile in a nicely formatted html page.

Here is the (part) of the code I need help with:
while (<LOOPFILE>) { $linenumber ++; @lineItems = split (/\t/); #... print OUTFILE "<BR><B>$lineItems[0]</b> ($lineItems[1])\n"; #.... } require "footer.pl"; close (LOOPFILE);

After I used the split, can I still somehow sort my flatfile (which is in @lineitems)? I need to have the [0]th element sorted alphabetically and I'm stuck. Any help much appreciated. Please know also that I have limited knowledge left and no time or permission to access and/or add modules etc. Thank you all SO MUCH for your help and I'm glad to see PM still going strong.


Cheers!

Replies are listed 'Best First'.
Re: FlatFile Sort Help
by MidLifeXis (Monsignor) on Nov 05, 2008 at 19:05 UTC

    If your file is small enough to read into memory, you could sort your input as you read it in:

    foreach (sort <LOOPFILE>) {...}

    Also, be aware that the last element in @lineitems will still contain a newline character.

    --MidLifeXis

      Thanks for the reminder about the \n and for the reply. Would I be able to do something like this then?

      while (<LOOPFILE>) { foreach (sort <LOOPFILE>) { $linenumber ++; @lineItems = split (/\t/); #... print OUTFILE "<BR><B>$lineItems[0]</b> ($lineItems[1])\n"; #.... } } require "footer.pl"; close (LOOPFILE);
      Thank you...and and sincerely appreciate the help and please don't giggle, I'm trying to jog what little memory I have.
        Remove the while.
        while (<LOOPFILE>) { # Reads first line foreach (sort <LOOPFILE>) { # Reads the rest of the line.

        So you'll end up printing everything but the first line.

        Drop the while loop and you should be fine.
Re: FlatFile Sort Help
by mr_mischief (Monsignor) on Nov 05, 2008 at 19:19 UTC
    Taking that snippet in isolation, the lines of the flat file are not in @lineitems. The lines of the flat file are being retrieved one at a time by the while ( <LOOPFILE> ) construct.

    What you could do is grab the whole file into memory as an array of lines, sort it, and then split it. It will give the same effect as splitting then sorting on the first element unless the entire first element is the same in two or more lines.

    my @lines = sort <LOOPFILE>; foreach ( @lines ) { # chomp; my @lineItems = split /\t/; # ... print OUTFILE "<br><b>$lineItems[0]</b> ($lineItems[1])\n"; # ... }

    If you must sort after the split, you can always have an array of arrays. You can sort the outer array by the first element of each inner one.

    my @lines = <LOOPFILE>; my @unsorted; foreach ( @lines ) { # chomp; my @lineItems = split /\t/; push @unsorted, \@lineItems; } my @sorted = sort { $a->[0] cmp $b->[0] } @unsorted; foreach ( @sorted ) { print OUTFILE '<br><b>', $_->[0], '</b> (', $_->[1], ")\n"; }

    BTW, those probably are in need of a chomp() where noted, but they are commented out because I didn't see where you had been using them.

      Thank you! I have it working perfectly. Have a great day all!