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

Hello everyone, I am pretty new to Perl and in the process of learning how to code using Perl. I am trying to do the following and don't know where to begin. Here is what I am trying to do. I have a file which will be read in line by line, each line is being place into an array. The file contains lines of text as shown below.
#Comment *ss id addr id: 099 bbb ccc aaa *ss id addr id: 003 aaa bbb ccc #Comment 2 *333 23 ss id: 002 aaa bbb ccc *22 233333333 34432 233 44
What I am trying to do is sort the lines by the pattern "/id\:\s?(0-9)" and if a line does not contain the "sid: number" then just print the line as it is in the file. so the new output file would contain the following
#Comment *333 23 ss id: 002 aaa bbb ccc *ss id addr id: 003 aaa bbb ccc #Comment 2 *ss id addr id: 099 bbb ccc aaa *22 233333333 34432 233 44
Thanks in advance for the help and please let me know if I need to clarify anything. thanks again

Replies are listed 'Best First'.
Re: Please help with sorting/sort
by kyle (Abbot) on Feb 14, 2008 at 16:55 UTC

    I'm not sure I'm clear on your requirements. It seems that you want to sort the matching lines but leave all the other lines in whatever location you found them.

    my @lines = <DATA>; my @matching_indices = grep $lines[$_] =~ /id:\s?\d/, 0 .. $#lines; my @matching_lines = @lines[@matching_indices]; my @sorted_matching_lines = sort { my ($an) = ( $a =~ /id:\s?(\d+)/ ); my ($bn) = ( $b =~ /id:\s?(\d+)/ ); $an <=> $bn } @matching_lines; @lines[@matching_indices] = @sorted_matching_lines; print @lines; __DATA__ #Comment *ss id addr id: 099 bbb ccc aaa *ss id addr id: 003 aaa bbb ccc #Comment 2 *333 23 ss id: 002 aaa bbb ccc *22 233333333 34432 233 44

    Here's the output:

    #Comment *333 23 ss id: 002 aaa bbb ccc *ss id addr id: 003 aaa bbb ccc #Comment 2 *ss id addr id: 099 bbb ccc aaa *22 233333333 34432 233 44
      WOW, thanks for the quick reply it WORKS GREAT!! Thanks for the help Kyle!!
Re: Please help with sorting/sort
by NetWallah (Canon) on Feb 14, 2008 at 17:41 UTC
    Here is a memory and CPU optimized version of kyle (++) 's solution:
    #! /usr/bin/perl use strict; my @lines = <DATA>; my @matching = map {{IDX=>$_, ID_KEY => ( $lines[$_] =~ /id:\s?(\d+)/ + )}} grep $lines[$_] =~ /id:\s?\d/, 0 .. $#lines; my @sorted_matching = sort { $a->{ID_KEY} <=> $b->{ID_KEY} } @matching; @lines[map {$_->{IDX} } @matching] = @lines[map {$_->{IDX}} @sorted_matching]; print @lines; __DATA__ #Comment *ss id addr id: 099 bbb ccc aaa *ss id addr id: 003 aaa bbb ccc #Comment 2 *333 23 ss id: 002 aaa bbb ccc *22 233333333 34432 233 44
    Memory is optimized because this avoids copying the entire $line[$_] for sort purposes. Instead, it copies only the extracted sort key, and index. Since the regular-expression for extracting the sort key is performed only once per record (instead of on each compare on the sort), CPU is optimized.

    I would be the first to admit that this probably classic "premature optimization" if the data size and frequency of use is small, but it was fun.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: Please help with sorting/sort
by jrsimmon (Hermit) on Feb 14, 2008 at 17:38 UTC
    This isn't as concise as the first example above, but it's an example of how to use a Schwartzian Transform (which I'm just beginning to learn).
    use strict; use warnings; my @data = ('#Comment', '*ss id addr id: 099 bbb ccc aaa', '*ss id add +r id: 003 aaa bbb ccc', '#Comment', '*333 23 ss id: 002 aaa bbb ccc', + '*22 233333333 34432 233 44'); my @id= (); foreach my $entry (@data){ if($entry =~ /id:/){ push(@id, $entry); } } my @sortedid = sort {$a->[1] <=> $b->[1]} map{[$_,/id:\s*(\d+)/]} @id; foreach my $entry (@data){ if($entry =~ /id:/){ my $sort = shift(@sortedid); print $sort->[0]; }else{ print $entry; } print "\n"; }
    Produces the same output as above:
    #Comment *333 23 ss id: 002 aaa bbb ccc *ss id addr id: 003 aaa bbb ccc #Comment *ss id addr id: 099 bbb ccc aaa *22 233333333 34432 233 44
Re: Please help with sorting/sort
by apl (Monsignor) on Feb 14, 2008 at 17:09 UTC
    I don't understand your filtering / display requirements; your example doesn't clarify the situation.

    A friendly suggestion: please show us what you've written, and then point to the areas you're uncertain about. We'll be happy to answer your questions. But you seem to be saying you don't know how to open a file, how to read a recod from the file into an array, how to do a regex, how to write to an output file.

    If you don't know how to do any of that, and won't ask your teacher for a tutor, we'd be doing you a disservice by writing your entire assignment for you.