![](/img/trans.png)
[英]How to open/join more than one file (depending on user input) and then use 2 files simultaneously
[英]Unix join on more than two files
我有三个文件,每个文件都有一个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.
我也知道粘贴可以使用“ - ”将STDIN作为参数之一。 例如,我可以使用以下命令复制join命令:
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等等。但这会变得混乱,我想用一个班轮做这件事。
join a.txt b.txt|join - c.txt
应该足够了
既然你是在Perl脚本中进行的 ,那么你是否有任何特定的理由不在Perl中进行工作而不是在shell中生成?
像(没有测试!警告经纪人):
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";
}
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的第一列。
perl -lanE'$h{$F[0]} .= " $F[1]" END{say $_.$h{$_} foreach keys %h}' *.txt
应该工作,不能测试它,因为我正在从我的手机回答。 如果在foreach
和keys
之间进行sort
,也可以对输出进行sort
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.