From: Pietro on
Hallo, I made a little script that sort the lines of a file:

#! /usr/bin/perl

sub numerically {$a <=> $b;}

@array = <>;

@array = sort numerically (@array);

print (@array);

Maybe the code is not so good, but why if I give thi input file:

1.3.5.6
1.1.2.4
111.222.444.555
1.2.5.6
11.22.44.55
1.2.3.4
11.23.66.77
11.22.33.44
111.222.333.444
11.22.44.55
111.223.333.444
11.22.33.44
1.2.3.4
11.22.22.22
11.22.55.66
1.2.4.5
111.222.555.666
1.1.2.3
1.3.4.5

The result is this:

1.1.2.4
1.1.2.3
1.2.5.6
1.2.3.4
1.2.3.4
1.2.4.5
1.3.5.6
1.3.4.5
11.22.44.55
11.22.33.44
11.22.44.55
11.22.33.44
11.22.22.22
11.22.55.66
11.23.66.77
111.222.444.555
111.222.333.444
111.222.555.666
111.223.333.444

As I see perl sots only the first two field delimited by a ".", the others
are inserted as a fifo, first line encountered first line wrote in output,
why doesn't perl compare all the line?

Thanks, Pietro.
--
I will build myself a copper tower
With four ways out and no way in
But mine the glory, mine the power
(So I chose AmigaOS and GNU/Linux)

From: Stephen Hildrey on
Pietro wrote:
> As I see perl sots only the first two field delimited by a ".", the others
> are inserted as a fifo, first line encountered first line wrote in output,
> why doesn't perl compare all the line?

You're using a *numeric* sort. "1.3.5.6" etc are not numbers.

If you had "use warnings;", you would see a load of these:

Argument "1.1.2.4\n" isn't numeric in numeric comparison (<=>)

Steve
From: Brian McCauley on
Pietro wrote:

> sub numerically {$a <=> $b;}
>
> Maybe the code is not so good, but why if I give thi input file:
>
> 1.3.5.6
> 1.1.2.4
> 111.222.444.555

> As I see perl sots only the first two field delimited by a ".", the others
> are inserted as a fifo, first line encountered first line wrote in output,

No, Perl sort the strings as numbers. If you convert the string
'1.3.5.6' to a number then you get the number 1.3 (and you'll get a
warning too if you've enabled warnings.

Sounds to me like you may want to compare the strings as IP address.

There are modules on CPAN to manipulate IP addresses.

From: J?rgen Exner on
Pietro wrote:
> Hallo, I made a little script that sort the lines of a file:
>
> #! /usr/bin/perl
> sub numerically {$a <=> $b;}
> @array = <>;
> @array = sort numerically (@array);
> print (@array);
>
> Maybe the code is not so good, but why if I give thi input file:
>
> 1.3.5.6
> 1.1.2.4
[...]
> 111.222.555.666
> 1.1.2.3
> 1.3.4.5
>
> The result is this:
>
> 1.1.2.4
> 1.1.2.3
> 1.2.5.6
[...]
> 111.222.444.555
> 111.222.333.444
> 111.222.555.666
> 111.223.333.444
>
> As I see perl sots only the first two field delimited by a ".",

Well, no. Perl is sorting _numerically_, just as you asked it to do.
And the numerical value of e.g. the string 1.3.4.5 happens to be 1.3.

> the
> others are inserted as a fifo, first line encountered first line
> wrote in output,

Yep, that's a great feature. It is called a 'stable sort'. If two items have
the same sort value, e.g. 111.222.444.555 and 111.222.333.444 which both
have the value of 111.222, then since version 5.8 perl ensures that their
relative position is not changed. Comes in very handy if you have to sort by
multiple keys, e.g. first by first name, then by last name.

> why doesn't perl compare all the line?

But perl does compare all the line. Or rather the numerical value of the
line just as you told it to do.

jue


From: William James on
Pietro wrote:

> Maybe the code is not so good, but why if I give thi input file:
>
> 1.3.5.6
> 1.1.2.4
> 111.222.444.555
> 1.2.5.6
> 11.22.44.55
> 1.2.3.4
> 11.23.66.77
> 11.22.33.44
> 111.222.333.444
> 11.22.44.55
> 111.223.333.444
> 11.22.33.44
> 1.2.3.4
> 11.22.22.22
> 11.22.55.66
> 1.2.4.5
> 111.222.555.666
> 1.1.2.3
> 1.3.4.5
>
> The result is this:
>
> 1.1.2.4
> 1.1.2.3
> 1.2.5.6
> 1.2.3.4
> 1.2.3.4
> 1.2.4.5
> 1.3.5.6
> 1.3.4.5
> 11.22.44.55
> 11.22.33.44
> 11.22.44.55
> 11.22.33.44
> 11.22.22.22
> 11.22.55.66
> 11.23.66.77
> 111.222.444.555
> 111.222.333.444
> 111.222.555.666
> 111.223.333.444
>
> As I see perl sots only the first two field delimited by a ".", the others
> are inserted as a fifo, first line encountered first line wrote in output,
> why doesn't perl compare all the line?

Pietro, I think it would be easier using Ruby.

----- program starts here -----

puts DATA.read.sort_by{ |x| x.split('.').map{|s| s.to_i} }

__END__
1.3.5.6
1.1.2.4
111.222.444.555
1.2.5.6
11.22.44.55
1.2.3.4
11.23.66.77
11.22.33.44
111.222.333.444
11.22.44.55
111.223.333.444
11.22.33.44
1.2.3.4
11.22.22.22
11.22.55.66
1.2.4.5
111.222.555.666
1.1.2.3
2.3.4.5
----- program ends here -----

The output is:

1.1.2.3
1.1.2.4
1.2.3.4
1.2.3.4
1.2.4.5
1.2.5.6
1.3.5.6
2.3.4.5
11.22.22.22
11.22.33.44
11.22.33.44
11.22.44.55
11.22.44.55
11.22.55.66
11.23.66.77
111.222.333.444
111.222.444.555
111.222.555.666
111.223.333.444