×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

sort file

sort file

sort file

(OP)
I need sort a flat file on one field. Seems like very simple, but it doesn't work for me. When i print out the datafile, the sorted file is same as the original one. I have no idea what i did wrong. Please help!! Thanks!
the following is my script:

my @data;
while ($line = <IN>){
        push @data, ( split(/\[\w*\]+/, $line)) ;
}
print "@data<br>\n";
 
my @sorted = sort{$a->[1] <=> $b->[1]} @data ;
 
print "@sorted\n";
 

RE: sort file

It needs to turn the (split ...) into an arrayref. Brackets added:

    push @data, [ (split(/\[\w*\]+/, $line)) ];

will do that.  Then your sort block will work as it stands.

"If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."

RE: sort file

(OP)
Thank you!!
But why can't I print my data out. when I tried to print it, nothing came out. but  I got the memory location.

my @data;
while ($line = <IN>){
        push @data, [( split(/\[\w*\]+/, $line))] ;
}
#print "@data<br>\n";
 
my @sorted = sort{$a->[6] <=> $b->[6]} @data ;
 
#print "@sorted\n"; #will get ARRAY(0x807f664) etc.
 
#@sorteddata = @$sorted;
#print "@sorteddata\n";      #nothing be printed
 
print "@{$sorted}\n"; #nothing come out

RE: sort file

because it's a reference to the actual arrays, not the data itself.  each element is an array ref, so the actual data has to be dereference once per row:
map {print @{$_}, "\n"} @sorted;
print "<br>\n";

also, the array '@sorted' is an actual array, you don't need to dereference it, in fact, trying to dereferencing it as you did produces no output(as you found out).  also, in case it isn't clear, the 'map' statement about works about the same as a 'foreach' loop, if you'd prefer that syntax.  either way, you have to be sure to iterate over all the elements of the array, dereferencing as you go.
good luck

"If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."

RE: sort file

(OP)
It is working now.
Thanks a lot!!!

RE: sort file

(OP)
Got a problem , need your help again!!!
 How can I get the new sorted array with the same format as my original one? my test file only has six field, now I can even get $new[20]. It means my whole file now has only one record.

my @data;
while ($line = <IN>){
        push @data, [( split(/\[\w*\]+/, $line))] ;
}
 
my @sorted = sort{$a->[1] cmp $b->[1]} @data ;
 
@new = map {@{$_},"\n"} @sorted;
 
print "<br>$new[20]\n";  #in my original file, only has 6 fields.now it prints out the
                                      #the third field of the third record.
print "<br>@new\n";

RE: sort file

(OP)
Err...  I do not understand the intent of the line:
print "<br>$new[20]\n";

Original form means one of two things.  Either you mean back into a flatfile database, or into the format you were originally trying to read it in as.  I doubt you want it back into the flatfile format, but i'm not sure why you would want it in the original format you were reading it in as.  The data is all there to be manipulated however you need, you'll just have to dereference each row to get at it's entries.  reading "perldoc perlref" could help you become more aquainted with how to do this.  In your case, though, it would be as easy as "$sorted[3][0]" or
"$sorted[5][2]" or whatever numbers corresponded to the row number (minus 1) and the entry number (minus 1), in that order.
 However, if you just want the exact form your original script read it into:
@old_format = map {@{$_}} @sorted;

all you were doing wrong was the "\n" of mine was intended to be printed, otherwise it adds an extra (and useless, now that i think about it.  the original newlines from the file were left in) entry for every row, thus throwing off your count.

RE: sort file

(OP)
Hi, I am sorting file by date now, but  couldn't get the correct result. If  I sort by any other values, it works fine. So I think the problem is the converttime function. But I can't figure out what I did wrong.
Please help!!!!
Thank you.

my @data;
while ($line = <IN>){
    push @data, [( split(/\[\w*\]+/, $line))] ;
}

 my @sorted =
    sort { &converttime($a->[22]) <=> &converttime($b->[22])} @data ;

#print out all the records in the file, they are sorted by the activedate

foreach (@sorted) {
$listing = "$_->[22],
        $_->[2],
               $_->[3],
                  $_->[4],
        $_->[5],
        $_->[6]
        $_->[7]";

print "$listing<br>\n";
}

# convert m/d/y format into Perl's seconds-since-1900  format.  I have # include theTime::Local module

sub converttime {
    my $date;
    if ($date eq "") {     #error formatting , sort to top. this part doesn't work                                                                                                                      #either,if the $date is empty, that record won't show up                                                                                                                              #in my print list.
        return 0;
    } else {
        my ($m,$d,$y) = split(/\//,$date);
        $m--;
        return timelocal(0,0,0,$d,$m,$y);
    }
}


RE: sort file

your problem is a simple oversight: the first line of your &convertdate should be:

my $date = shift or return 0;


the '= shift' part is all you really need, but i put the 'or return 0' part in because then you can skip the if/else statement below it (for the assignment of $date, if it's "", that will evaluate to false, causing the 'return 0' part to be executed), turning it into:

sub convertdate
{
   my $date = shift or return 0;
   my ($m,$d,$y) = split(/\//,$date);
   $m--;
   return timelocal(0,0,0,$d,$m,$y);
}

"If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."

RE: sort file

(OP)
It doesn't work. After I changed it into " my $date = shift ;", I got a "server error" message on the browser, but there is no problem  when I run it under UNIX.
Why I   need use the shift function?
Thanks a lot!

RE: sort file

(OP)
I found out that the problem could be
my @sorted =
                   sort { &converttime($a->[22]) <=> &converttime($b->[22])} @data;
because when I tried to print out $date in converttime(), if it is "my $date;"
nthing will be printed out, $date is empty. If it is "my $date = shift:" got  server error(I guee since there is nothing being passed to the function, so can't do the shift)
Is it the right way to call a function in the reference like this?
If I don't call the function converttime(), it'll sort the file by the $m $d $y. Of course that is not what I want. I want it sorted by $y $m $d.
Looking forward to hearing from you!!!
Thank you.

RE: sort file

hrmm..
first question first.  the '=shift' part is because when you call the subroutine, you're passing it an argument.  that argument gets brought into the sub as the array '@_'.  since you need to use the data that's being passed into the subroutine, you need to get that data out of the array and use it (you could even leave it in, and just reference it as $_[0], but that's a little too cryptic and sloppy).  when more arguments are passed, the array will of course have more entries.  well, anyway, the '=shift' part makes '$data' have the value that the first element of that array has, which is what you want.
now, as to the server error...  i don't know.  if it is as you say, and it runs fine on the command line, but fails in the browser, it may be improper permissions on a file used or some problem involving database accessing (which you aren't doing)
however, since you say this problem has only occurred due to the recent changes you have made, and that specifically the line '=shift' is causing it, i can't say.
what is the exact text of the sub as it currently stands?  is it the one i wrote, or different.  my subroutine compiles and works fine on my system.  even if there's nothing to be passed to it, that'll just cause the subroutine to return zero (that's another benefit of the 'or return 0;' part)  
it could be that the syntax of the dates isn't in the format you think it is (it may have spaces or something in it that you'll need to remove or avoid), but at this point, i don't have enough information to diagnose your problem.
sorry.

"If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."

RE: sort file

(OP)
stillflame:
Thank you.  You are great!!!!!!!!
You are right. the problem is the syntax of the date. When I use a simple file to test the code, it works fine.
 My data file has thousands of records. some of them are in the format  like  01-03-00, some of them are empty. I hasn't finished the checking, but now I know they are not all in the standard format. I am trying to find a way to avoid all these unstandard date and sort them to the top:
     
sub convertdate {
        my $date = shift ;
        if ($date =~ /\/*\/*\/*/ ) {
        my ($m,$d,$y) = split(/ \/ /,$date);
        $m--;
        return timelocal(0,0,0,$d,$m,$y);
 
        }
        else
        {
        return 0;
        }
 
}

it works on command line, but got "server eorror" message on the browser.
is $date =~ /\/*\/*\/*/ right for the */*/*/ format? what is the best way to do this job? Correct the file record first, or just sort them to the top. How to sort all the unstandard date to the top?
Thank you.
 

RE: sort file

a regex for mm/dd/yy is:
m~(\d+?)\/(\d+?)\/(\d+?)~
which then assigns the three numbers to $1, $2, and $3.  so you would then say:
($m, $d, $y) = ($1, $2, $3);

if it's feasable to standardize the dates in all the records, you can do that.  but that doesn't prevent this from happening again.  you could create a subroutine that converts all the known types of formats into a single standard format.  this subroutine could then be used both to convert every date on file to the standard, or it could be used to convert them on the fly, or (preferably) both.  this would be a regex intense operation to undertake, but would make your code much more flexable.

good luck.

"If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."

RE: sort file

(OP)
stillflame :
  Thanks a lot!
  I have got my job done.
kate.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login


Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close