Возможно ли использовать два ключа и значения для объединения нескольких файлов? - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь объединить 3 файла
Файл 1: файл с разделителями табуляции из 4 столбцов

ID   Column_1    Column_2     Column_3    
 A     100       100001         X   
 B     100        99999         Y     
 C     100        88888         Z    
 D      99       100001         Y   
 E      99        88888         Z       

Файл 2: Файл с разделителями табуляции из 3 столбцов

  Column_4    Column_5     Column_6    
  100       100001         X   
  100        99999         Y     
  100        88888         Z    
   99       100001         Y   
   99        88888         Z 

Файл 3: Файл с разделителями табуляции в 4 столбцах

 Column_7    Column_8     Column_9   Column_10   
    100       120000        100       100001
    100        66666        100        99999
    100        77777        100        88888
     99        100000        99       100001
     99        44444         99        88888  

Я хочу создать файл слияния

 ID  Column_1   Column_2   Column_3  Column_6  Column_7  Column_8  
 A     100       100001         X       X       100       120000 
 B     100        99999         Y       Y       100        66666
 C     100        88888         Z       Z       100        77777
 D      99       100001         Y       Y        99       100000   
 E      99        88888         Z       Z        99        44444  

Я пытаюсь использовать хэш-подход в зависимости от столбцов 1 и 2. Но я только что узналчто у меня есть два ключа и много значений.Как я могу использовать хеш для разбора этих файлов?

1 Ответ

0 голосов
/ 25 февраля 2019

Вы находитесь на правильном пути с хэшем, вам просто нужно вычислить ключ по столбцам для каждой таблицы.Раздел решения:

  • чтение каждой строки из 3 файлов TSV, используя Text :: CSV
    • для каждой строки, вызовите код, специфичный для таблицыref
    • извлечь 2 столбца, которые необходимы для ключа, и объединить их со строкой ключа $key
    • для первой таблицы: сохранить ключ в массиве @order, т.е. он определяетпорядок вывода таблицы
    • в хэше %table под ключом $key: перенести столбцы, идущие из этой таблицы в финальную таблицу, в массив ref
  • зацикливание @order
    • извлечение ссылки на массив в $key из хэша %table
    • строки дампа в качестве TSV с использованием Text :: CSV до STDOUT
#!/usr/bin/perl
use warnings;
use strict;
use autodie;

use Text::CSV;

my $csv = Text::CSV->new({
    binary   => 1,
    eol      => "\n",
    sep_char => "\t",
}) or die "CSV creation\n";

sub read_file($$) {
    my($file, $code) = @_;
    open(my $fh, '<', $file);
    while (my $row = $csv->getline( $fh )) {
        $code->($row);
    }
    $csv->eof or $csv->error_diag();
    close($fh);
}

# Output table + row order
my %table;
my @order;

# Table 1
read_file($ARGV[0], sub {
    my($row) = @_;

    #print "ROW 1 @{ $row }\n";
    my($col1, $col2) = @{ $row }[1,2];

    # column_1, column_2 define key
    my $key = "${col1}${col2}";
    #print "KEY 1 ${key}\n";

    # table 1 defines order
    push(@order, $key);
    # ID, column_1, column_2, column_3 from table 1
    $table{$key} = $row;
});

# Table 2
read_file($ARGV[1], sub {
    my($row) = @_;

    #print "ROW 2 @{ $row }\n";
    my($col4, $col5, $col6) = @{ $row };

    # column_4, column_5 define key
    my $key = "${col4}${col5}";
    #print "KEY 2 ${key}\n";

    # column_6 from table 2
    push(@{ $table{$key} }, $col6);
});

# Table 3
read_file($ARGV[2], sub {
    my($row) = @_;

    #print "ROW 3 @{ $row }\n";
    my($col7, $col8, $col9, $col10) = @{ $row };

    # column_7, column_10 define key
    my $key = "${col7}${col10}";
    #print "KEY 3 ${key}\n";

    # column_7, column_8 from table 2
    push(@{ $table{$key} }, $col7, $col8);
});

foreach my $key (@order) {
    $csv->print(\*STDOUT, $table{$key});
}

exit 0;

Тестовый прогон:

$ perl dummy.pl dummy1.txt dummy2.txt dummy3.txt 
A       100     100001  X       X       100     120000
B       100     99999   Y       Y       100     66666
C       100     88888   Z       Z       100     77777
D       99      100001  Y       Y       99      100000
E       99      88888   Z       Z       99      44444
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...