基于多列加入三个文本文件

时间:2014-05-23 15:39:16

标签: perl unix

我想基于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来实现这一点吗?

2 个答案:

答案 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