Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Perl sorting multiple columns

Status
Not open for further replies.

vquick

IS-IT--Management
Jul 13, 2008
14
US
Im am struggling with a script to sort by column 2 first and then column 4. Here is what my list looks like:
E78343 2008/07/26 08:54:29 TYPE1
E78351 2008/07/26 08:54:30 TYPE2
E78365 2008/07/26 08:54:32 TYPE1
E42692 2008/07/26 10:08:02 TYPE1
E243687 2008/07/26 10:14:58 TYPE3
E64527 2008/07/30 07:56:36 TYPE1
E75799 2008/07/31 07:40:11 TYPE2
E75808 2008/07/31 07:40:11 TYPE2
E75830 2008/07/31 07:40:18 TYPE3

here is what ive tried:
#!/usr/bin/env perl

any help would be appreciated

open(IN, "sorted.lst");
@data = <IN>;

@sorted_users =
map { $_->[2] }
sort { $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] }
map { [ length $_[1], $_[0], $_ ] } # step 1
@data;

print "@sorted_users";
 
You need to add some additional steps in there, see if you understand what I did, if not, ask questions:

Code:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]warnings[/green][red];[/red]
[black][b]use[/b][/black] [green]strict[/green][red];[/red]
[url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url][red]([/red]IN, [red]"[/red][purple]sorted.lst[/purple][red]"[/red][red])[/red] or [url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple][blue]$![/blue][/purple][red]"[/red][red];[/red]
[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]@data[/blue] = <IN>[red];[/red]
close IN[red];[/red]
[url=http://perldoc.perl.org/functions/chomp.html][black][b]chomp[/b][/black][/url] [blue]@data[/blue][red];[/red]

[black][b]my[/b][/black] [blue]@sorted_users[/blue] =
     [url=http://perldoc.perl.org/functions/map.html][black][b]map[/b][/black][/url]  [red]{[/red] [blue]$_[/blue]->[red][[/red][fuchsia]0[/fuchsia][red]][/red] [red]}[/red]
     [url=http://perldoc.perl.org/functions/sort.html][black][b]sort[/b][/black][/url] [red]{[/red] [blue]$a[/blue]->[red][[/red][fuchsia]1[/fuchsia][red]][/red] cmp [blue]$b[/blue]->[red][[/red][fuchsia]1[/fuchsia][red]][/red] || [blue]$a[/blue]->[red][[/red][fuchsia]2[/fuchsia][red]][/red] cmp [blue]$b[/blue]->[red][[/red][fuchsia]2[/fuchsia][red]][/red] [red]}[/red]
     [black][b]map[/b][/black]  [red]{[/red] [black][b]my[/b][/black] [blue]@t[/blue] = [url=http://perldoc.perl.org/functions/split.html][black][b]split[/b][/black][/url][red]([/red][red]/[/red][purple][purple][b]\s[/b][/purple]+[/purple][red]/[/red],[blue]$_[/blue][red])[/red][red];[/red]
            [black][b]my[/b][/black][red]([/red][blue]$y[/blue],[blue]$d[/blue],[blue]$m[/blue][red])[/red]=[black][b]split[/b][/black][red]([/red][red]/[/red][purple][purple][b]\/[/b][/purple][/purple][red]/[/red],[blue]$t[/blue][red][[/red][fuchsia]1[/fuchsia][red]][/red][red])[/red][red];[/red]
            [red][[/red][blue]$_[/blue],[red]"[/red][purple][blue]$y[/blue][blue]$m[/blue][blue]$d[/blue][/purple][red]"[/red],[blue]$t[/blue][red][[/red][fuchsia]3[/fuchsia][red]][/red][red]][/red][red];[/red] [red]}[/red]  [blue]@data[/blue][red];[/red]

[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]"[/red][purple][blue]$_[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red] [olive][b]for[/b][/olive] [blue]@sorted_users[/blue][red];[/red]
[tt]------------------------------------------------------------
Pragmas (perl 5.10.0) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[li]warnings - Perl pragma to control optional warnings[/li]
[/ul]
[/tt]

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Your script is not trying to do what you state: seems its intent, though with a basic error (lack of split) as pointed out by Kevin, is to sort on length of 2nd column (which is constant length!) then on first column. You should better specify your intent, providing the sorted output you want.
This would anyway be a simpler to read (and possibly more efficient) way of sorting on column 2 then 4:
Code:
my@data=map{[split]}<DATA>;
@data=sort{$$a[1]cmp$$b[1]||$$a[3]cmp$$b[3]}@data;
@data=map{join(' ',@{$_})."\n"}@data;
print@data;
__DATA__
E78343 2008/07/26 08:54:29 TYPE1
E78351 2008/07/26 08:54:30 TYPE2
E78365 2008/07/26 08:54:32 TYPE1
E42692 2008/07/26 10:08:02 TYPE1
E243687 2008/07/26 10:14:58 TYPE3
E64527 2008/07/30 07:56:36 TYPE1
E75799 2008/07/31 07:40:11 TYPE2
E75808 2008/07/31 07:40:11 TYPE2
E75830 2008/07/31 07:40:18 TYPE3
output:
Code:
E78343 2008/07/26 08:54:29 TYPE1
E78365 2008/07/26 08:54:32 TYPE1
E42692 2008/07/26 10:08:02 TYPE1
E78351 2008/07/26 08:54:30 TYPE2
E243687 2008/07/26 10:14:58 TYPE3
E64527 2008/07/30 07:56:36 TYPE1
E75799 2008/07/31 07:40:11 TYPE2
E75808 2008/07/31 07:40:11 TYPE2
E75830 2008/07/31 07:40:18 TYPE3

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
I see I made an error in my code, the date should be ymd to sort as a string, which it already is, there was no need to reformat the date. Not sure what I was thinking, or not thinking.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top