-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmysort
executable file
·111 lines (107 loc) · 2.07 KB
/
mysort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/perl
use strict;
my @ks;
my %typeh = ();
my $revfactor = 1;
my $isnum = 0;
my $thresh;
my $threshk;
my $top_n = undef;
my $has_header = 0;
while ($ARGV[0] =~ /^\-/) {
my $opt = shift;
if ($opt eq '-k') {
@ks = (getk(shift @ARGV));
}
elsif ($opt eq '-r') {
$revfactor = -1;
}
elsif ($opt =~ /^\-t(\d+)/) {
$threshk = $1;
$thresh = shift @ARGV;
}
elsif ($opt eq '-n') {
$isnum = 1;
}
elsif ($opt eq '-N') {
for my $k (getk(shift @ARGV)) {
$typeh{$k} = 'n';
}
}
elsif ($opt eq '--top') {
$top_n = shift;
}
elsif ($opt eq '-s' || $opt eq '--has-header') {
$has_header = 1;
}
elsif ($opt =~ /\-k(\S+)/) {
@ks = map {getk($_)} split(',',$1);
}
}
if ($isnum) {
$typeh{$_} = 'n' foreach @ks;
}
my @rows = ();
while(<>) {
if ($has_header) {
$has_header = 0;
print;
next;
}
chomp;
my $row = [split(/\t/)];
if ($threshk) {
if ($row->[$threshk-1] < $thresh) {
next;
}
}
push(@rows,$row);
}
@rows = sort { mycmp () } @rows;
if ($top_n) {
my $lastby;
my $c=0;
foreach my $row (@rows) {
my $by = $row->[$ks[0]];
if ($by ne $lastby) {
$c=0;
}
$lastby = $by;
$c++;
if ($c <= $top_n) {
print join("\t",@$row)."\n";
}
}
}
else {
print join("\t",@$_)."\n"
foreach @rows;
}
exit(0);
sub mycmp {
my $cmp = 0;
my $i=0;
while (!$cmp && $i < scalar(@ks)) {
my $k = $ks[$i];
if ($typeh{$k} eq 'n') {
$cmp = $a->[$k] <=> $b->[$k];
}
else {
$cmp = $a->[$k] cmp $b->[$k];
}
$cmp *= $revfactor;
$i++;
}
return $cmp;
}
sub getk {
my $k = shift;
my $type = '';
if ($k =~ /^n(\d+)/) {
$k = $1;
$type = 'n';
}
$k--;
$typeh{$k} = $type;
return $k;
}