我想基于Unix中的多个列加入三个文本文件
我想在Perl脚本中使用
File1中
A|B|C|MIKE
D|E|F|BIKE
G|H|I|HELLO
文件2
A|B|C|123
D|E|F|456
G|H|I|789
A|A|A|121
B|B|B|221
文件3
G|H|I|ABC
A|A|A|BCA
B|B|B|CBA
最终输出
A|B|C|MIKE|123|
D|E|F|BIKE|456|
G|H|I|HELLO|789|ABC
A|A|A|121|BCA
B|B|B|221|CBA.
我不想使用创建一些临时文本文件的脚本,因为我的每个文本文件都非常大。我可以在Unix中使用join
来实现这一点吗?
答案 0 :(得分:2)
来自命令行的perl解决方案,
perl -F'\|' -lane'
BEGIN { $" = "|" }
$v = pop @F;
$h{"@F"} or push @r, "@F";
$h{"@F"}[$i] = $v;
$i++ if eof;
}{
print "@$_" for map [ $_, @{$h{$_}}[0..$i-1] ], @r
' file1 file2 file3
输出
A|B|C|MIKE|123|
D|E|F|BIKE|456|
G|H|I|HELLO|789|ABC
A|A|A||121|BCA
B|B|B||221|CBA
<强>说明强>
在打印输出之前,脚本会生成以下%h
哈希结构
$VAR1 = {
'G|H|I' => [
'HELLO',
'789',
'ABC'
],
'D|E|F' => [
'BIKE',
'456'
],
'B|B|B' => [
undef,
'221',
'CBA'
],
'A|A|A' => [
undef,
'121',
'BCA'
],
'A|B|C' => [
'MIKE',
'123'
]
};
答案 1 :(得分:1)
这是一个基本的程序,可以满足您的要求,但如果您的文件非常庞大,那么它可能会因内存不足而死亡。
这三个文件的名称在命令行中是预期的,因此应该以
的形式运行perl program.pl file1.txt file2.txt file3.txt > merge.txt
use strict;
use warnings;
my @keys;
my %data;
my $i = 0;
while (<>) {
next unless /\S/;
my ($key, $val) = /(.+)\|(.+)/;
push @keys, $key unless $data{$key};
$data{$key}[$i] = $val;
}
continue {
++$i if eof;
}
for my $key (@keys) {
print join('|', $key, map $_ // '', @{ $data{$key} }), "\n";
}
<强>输出强>
A|B|C|MIKE|123
D|E|F|BIKE|456
G|H|I|HELLO|789|ABC
A|A|A||121|BCA
B|B|B||221|CBA