- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - HP-UX
- >
- Using Sort in PERL
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Discussions
Forums
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-17-2006 07:47 AM
тАО05-17-2006 07:47 AM
boo1
boo10
boo2
foo1
foo2
foo20
foo3
foo4
...
Is there a way to get perl to sort alphanumically so it sorts like
boo1
boo2
...
boo10
??
I tried looking at some sort man pages but I can't find options like the unix sort.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-17-2006 08:14 AM
тАО05-17-2006 08:14 AM
Re: Using Sort in PERL
Assuming data as shown (3-letters followed by digits), this would work:
# perl -le '@a=qw(boo2 foo1 boo10 foo2 foo20 foo3 foo4);@a=sort{substr($a,0,3) cmp substr($b,0,3)||substr($a,3) <=> substr($b,3)} @a;print "@a"'
Regards!
...JRF...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-17-2006 08:49 AM
тАО05-17-2006 08:49 AM
Re: Using Sort in PERL
my @sorted = map { $_->[0] }
sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b=>[2] }
map { [ $_, ($_ =~ m/^([a-z]+)(\d+)/), "", 0 ]
@unsorted;
Enjoy, Have FUN! H.Merijn
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-17-2006 11:20 AM
тАО05-17-2006 11:20 AM
Re: Using Sort in PERL
If I use the approach you mentioned, how would I fit it in here:
my $temp;
for $temp ( sort keys %scalelist) {
my $rec = $scalelist{$temp};
do {
I'm trying to sort the keys which can be any length numeric string followed by a numberic string.
Ex:
xxxxx1
xxxxx10
xxxxx2
yyy1
yyy2
yyy20
yyy3
I'm just not sure how to put it in this statement. Maybe create a sub called NewSort and put that sub in place of the sort above???
Thanks in advance Jeff.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-17-2006 12:02 PM
тАО05-17-2006 12:02 PM
Re: Using Sort in PERL
Merijn's solution is by far more generalized for your data than mine, let alone much more efficient.
Assuming that you have collected your data in a hash called 'scalelist' with keys that look like your original post, do something like:
@sorted = map { $_->[0] }
sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] }
map { [ $_, ($_ =~ m/^([a-z]+)(\d+)/), "", 0 ] }
keys %scalelist;
foreach $key (@sorted) {
print "$key => $scalelist{$key}\n";
}
Regards!
...JRF...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-17-2006 12:31 PM
тАО05-17-2006 12:31 PM
Re: Using Sort in PERL
I got this error when trying that:
Useless use of spaceship operator in void context at line 183.
Sort subroutine didn't return a numeric value at line 185.
The lines correspond with the use of "map" syntax.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-17-2006 06:32 PM
тАО05-17-2006 06:32 PM
Solutionmy @sorted = map { $_->[0] }
sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] }
map { [ $_, ($_ =~ m/^([a-z]+)(\d+)/), "", 0 ] }
@unsorted;
Mea culpa.
lt09:/home/merijn 109 > cat test.txt
boo1
boo10
boo2
foo1
foo2
foo20
foo3
foo4
lt09:/home/merijn 110 > cat test.pl
#!/pro/bin/perl
use strict;
use warnings;
my @unsorted = <>;
my @sorted =
map { $_->[0] }
sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] }
map { [ $_, ($_ =~ m/^([a-z]+)(\d+)/), "", 0 ] }
@unsorted;
print @sorted;
lt09:/home/merijn 111 > perl test.pl test.txt
boo1
boo2
boo10
foo1
foo2
foo3
foo4
foo20
lt09:/home/merijn 112 >
OK, let's also explain.
@unsorted is your array
perl's 'map' transforms each element of the list passed to something else (that can be anything):
@high = map { $_ + 10 } 1..4;
In above case we pass the list (1, 2, 3, 4) to map. It gets each element in turn (in $_), and adds 10 to it, passing it along. So now @high is (11, 12, 13, 14)
For a S-T sort, the first map converts to an anonymous array
@both = map { [ $_, $_ + 10 ] } 1..4;
will transform the list 1,2,3,4 to ([1,11],[2,12],[3,13],[4,14])
It is common to put the original value in the first element of the list, and the values to sort on in the rest
Now the sort doesn't ket the original values, but a list of lists, where it can efficiently sort on the precalculated elements in the list, so the calculations only have to be done once, instead of on every comparison
map { [ $_, ($_ =~ m/^([a-z]+)(\d+)/), "", 0 ] }
$_ is your value
($_ =~ m/..../) is evaluated in list context, and thust returns the caught elements in $1 and $2. In even terser mode, I could have left out $_ =~, since that is the default for m//.
If that fails, it catches nothing, causing errors in the compare part, which is why I also added "", and 0 to the list. For good matches, these two are ignored in the sort phase, but are a catch-net for failed matches. So
map { [ $_, ($_ =~ m/^([a-z]+)(\d+)/), "", 0 ] } qw( boo1 boo12 frubble4 blast99 );
would return
[ "boo1", "boo", 1 ], [ "boo12", "boo", 12 ], [ "frubble4", "frubble", 4 ], [ "blast99", "blast", 99 ]
As you see this list contains all you need for a proper sort
the sort part sorts the anonymous lists on the second element (the letter part) with cmp, and if that is equal, on the numeric part with <=>
([ "boo1", "boo", 1 ], [ "boo12", "boo", 12 ], [ "blast99", "blast", 99 ], [ "frubble4", "frubble", 4 ])
That last map, just gets you the first element of the list out again, throwing the rest away
("boo1", "boo12", "blast99", "frubble4")
The Swartzian Transform is also described in the perl FAQ:
# perldoc -q 'How do I sort an array by (anything)?'
Enjoy, Have FUN! H.Merijn
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-18-2006 02:23 AM
тАО05-18-2006 02:23 AM