4

我有三个文件,每个文件都有一个 ID 和一个值。

sdt5z@fir-s:~/test$ ls
a.txt  b.txt  c.txt
sdt5z@fir-s:~/test$ cat a.txt 
id1 1
id2 2
id3 3
sdt5z@fir-s:~/test$ cat b.txt 
id1 4
id2 5
id3 6
sdt5z@fir-s:~/test$ cat c.txt 
id1 7
id2 8
id3 9

我想创建一个看起来像这样的文件......

id1 1 4 7
id2 2 5 8
id3 3 6 9

...最好使用单个命令。

我知道加入和粘贴命令。每次粘贴都会复制 id 列:

sdt5z@fir-s:~/test$ paste a.txt b.txt c.txt 
id1 1   id1 4   id1 7
id2 2   id2 5   id2 8
id3 3   id3 6   id3 9

加入效果很好,但一次只能处理两个文件:

sdt5z@fir-s:~/test$ join a.txt b.txt 
id1 1 4
id2 2 5
id3 3 6
sdt5z@fir-s:~/test$ join a.txt b.txt c.txt 
join: extra operand `c.txt'
Try `join --help' for more information.

我也知道 paste 可以通过使用“-”将 STDIN 作为参数之一。例如,我可以使用以下命令复制连接命令:

sdt5z@fir-s:~/test$ cut -f2 b.txt | paste a.txt -
id1 1   4
id2 2   5
id3 3   6

但我仍然不确定如何修改它以容纳三个文件。

因为我在 perl 脚本中执行此操作,所以我知道我可以将其放入 foreach 循环中,例如 join file1 file2 > tmp1、join tmp1 file3 > tmp2 等。但这会变得混乱,我想用单线做到这一点。

4

4 回答 4

12

join a.txt b.txt|join - c.txt

应该足够了

于 2012-02-09T14:49:22.623 回答
1

既然您是在Perl 脚本中执行此操作,那么与在 shell 中生成而不是在 Perl 中执行该工作有什么具体原因吗?

类似的东西(未测试!警告购买者):

use File::Slurp; # Slurp the files in if they aren't too big
my @files = qw(a.txt b.txt c.txt);
my %file_data = map ($_ => [ read_file($_) ] ) @files;
my @id_orders;
my %data = ();
my $first_file = 1;
foreach my $file (@files) {
    foreach my $line (@{ $file_data{$file} }) {
        my ($id, $value) = split(/\s+/, $line);
        push @id_orders, $id if $first_file;
        $data{$id} ||= [];
        push @{ $data{$id} }, $value;
    }
    $first_file = 0;
}
foreach my $id (@id_orders) {
    print "$d " . join(" ", @{ $data{$id} }) . "\n";
}
于 2012-02-09T14:50:38.753 回答
0

perl -lanE'$h{$F[0]} .= " $F[1]" END{say $_.$h{$_} foreach keys %h}' *.txt

应该可以,因为我正在通过手机回答,所以无法对其进行测试。如果您在andsort之间放置一个,您也可以对输出进行排序。foreachkeys

于 2012-02-09T16:33:13.850 回答
0
pr -m -t -s\  file1.txt file2.txt|gawk '{print $1"\t"$2"\t"$3"\t"$4}'> finalfile.txt

考虑到 file1 和 file2 有 2 列,1 和 2 代表来自 file1 的列,3 和 4 代表来自 file2 的列。

您还可以通过这种方式打印每个文件中的任何列,它将采用任意数量的文件作为输入。例如,如果您的 file1 有 5 列,则 $6 将是 file2 的第一列。

于 2013-04-16T09:03:04.800 回答