Как я могу идти через два файла одновременно в Perl?

У меня есть два текстовых файла, которые содержат колоночные данные разнообразия position-value, отсортированный по position.

Вот пример первого файла (файл A):

100   1
101   1
102   0
103   2
104   1
...

Вот пример второго файла (B):

20    0
21    0
...
100   2
101   1
192   3
193   1
...

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

То, что это означает, - то, что я хотел бы передать потоком через строки также A или B и сравните position значения.

Если эти два положения равны, то я выполняю вычисление на значениях, связанных с тем положением.

Иначе, если положения не равны, я перемещаюсь через строки файла A или файл B пока положения не равны (когда я снова выполняю свое вычисление), или я достигаю EOF обоих файлов.

Существует ли способ сделать это в Perl?

8
задан Alex Reynolds 24 March 2010 в 00:04
поделиться

3 ответа

Похоже на проблему, на которую можно было бы наткнуться, например, данные таблицы базы данных с ключами и значениями. Вот реализация псевдокода, предоставленного rjp.

#!/usr/bin/perl

use strict;
use warnings;

sub read_file_line {
  my $fh = shift;

  if ($fh and my $line = <$fh>) {
    chomp $line;
    return [ split(/\t/, $line) ];
  }
  return;
}

sub compute {
   # do something with the 2 values
}

open(my $f1, "file1");
open(my $f2, "file2");

my $pair1 = read_file_line($f1);
my $pair2 = read_file_line($f2);

while ($pair1 and $pair2) {
  if ($pair1->[0] < $pair2->[0]) {
    $pair1 = read_file_line($f1);
  } elsif ($pair2->[0] < $pair1->[0]) {
    $pair2 = read_file_line($f2);
  } else {
    compute($pair1->[1], $pair2->[1]);
    $pair1 = read_file_line($f1);
    $pair2 = read_file_line($f2);
  }
}

close($f1);
close($f2);

Надеюсь, это поможет!

6
ответ дан 5 December 2019 в 12:09
поделиться

Для перебора файлов вы можете использовать модуль core Tie :: File . Он представляет собой обычный текстовый файл в виде массива.

2
ответ дан 5 December 2019 в 12:09
поделиться

Если файлы отсортированы, пройдитесь по ним, основываясь на том, какой из них имеет более низкую позицию.

Псевдокод:

read Apos, Aval from A # initial values
read Bpos, Bval from B 
until eof(A) or eof(B)
  if Apos == Bpos then
    compare()
    read Apos, Aval from A # advance both files to get a new position
    read Bpos, Bval from B
  fi
  if Apos < Bpos then read Apos, Aval from A
  if Bpos < Apos then read Bpos, Bval from B
end

Вы также можете использовать join(1), чтобы выделить строки с общими позициями и обработать их на досуге.

4
ответ дан 5 December 2019 в 12:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: