-
Notifications
You must be signed in to change notification settings - Fork 2
/
tsvmerge.pl
executable file
·64 lines (56 loc) · 1.13 KB
/
tsvmerge.pl
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
#!/usr/bin/perl
use strict;
use warnings FATAL => qw/all/;
use autodie;
use File::Basename;
sub tsv (@);
sub usage {
die <<END;
Usage: @{[basename($0)]} [-N | +N] TSV_FILE...
Merge TSV_FILEs by -N-th column value.
- Default merge column is -1 (last column).
- Each TSV_FILE must have header line.
END
}
{
usage() unless @ARGV;
my $join_col = -1;
my %all;
my @header;
my $fileno = -1;
while (@ARGV) {
my $arg = shift @ARGV;
# Set $join_col when [-N | +N] is given.
if ($arg =~ /^([-+]\d+)$/) {
$join_col = $1;
next;
}
$fileno++;
my $fn = $arg;
open my $fh, "<", $fn;
local $_;
push @header, do {
chomp(my $line = <$fh>);
[split "\t", $line];
};
while (<$fh>) {
chomp;
my $tsv = [split "\t", $_];
$all{$tsv->[$join_col]}[$fileno] = $tsv;
}
}
print tsv(map {@$_} @header);
foreach my $key (sort keys %all) {
my $item = $all{$key};
print tsv map {
if ($item->[$_]) {
@{$item->[$_]}
} else {
('') x (@{$header[$_]})
}
} 0 .. $#$item;
}
}
sub tsv (@) {
join("\t", map {$_ // ''} @_)."\n";
}