Perl while циклы и чтение строк

Каждая запись состоит из 4 строк:

Как следующее:

@NCYC361­11a03.q1k bases 1 to 1576
GCGTGCCCGAAAAAATGCTTTTGGAGCCGCGCGTGAAAT
+
!)))))****(((***%%((((*(((+,**(((+**+,­

Есть два файла, в которых 1 файл соответствует другому

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


person A14    schedule 05.06.2012    source источник
comment
Правильно ли я понимаю, что в файлах могут совпадать только строки с одинаковым номером?   -  person Oleg V. Volkov    schedule 05.06.2012
comment
Какой внутренний цикл? Здесь нет внутреннего цикла.   -  person Qtax    schedule 05.06.2012
comment
Не могли бы вы объяснить, в чем ваша цель... вы хотите сравнить файлы?   -  person dgw    schedule 05.06.2012
comment
Ну, так как я по существу делаю это с каждой записью, которая имеет 4 строки. Итак, я читаю запись из файла 1, извлекаю ее, получаю последовательность. затем прочитайте 1-ю запись из файла 2 и выполните соответствующие действия по мере необходимости. Однако я застрял в том, как выйти из внутреннего цикла, снова прочитать следующую запись из файла 1...   -  person A14    schedule 05.06.2012


Ответы (4)


Если вы спросите об управлении вложенными циклами, вы можете сделать это с помощью меток.

Пример:

OUTER:
while(<>){
    for(@something){
        last OUTER;
    }
}

Например, см. last.

person Qtax    schedule 05.06.2012

В случае, если только строки с одинаковым номером могут когда-либо совпадать, вам действительно не нужно более одного цикла. Вы можете вызывать операцию чтения (<>, read, sysread) где угодно. Обычно его помещают непосредственно в цикл, потому что он удобно возвращает undef и прерывает его, когда работа выполнена.

while(defined(my $first_line = <FIRST>)){
   my $second_line = <SECOND>;
   if($first_line eq $second_line){
      print "match\n";
   } else {
      print "no match\n";
   }
}
person Oleg V. Volkov    schedule 05.06.2012

Из вашего предложения мне нужно проверить, совпадает ли какая-либо последовательность с последовательностью из второго, я понимаю, что вы хотите проверить, совпадают ли какие-либо строки в двух файлах?

Если вам нужно прочитать файл несколько раз, вы можете использовать seek, чтобы перемотать его к началу, не открывая его повторно.

Эта программа показывает идею.

use strict;
use warnings;

open my $fh1, '<', 'file1' or die $!;
open my $fh2, '<', 'file2' or die $!;

open my $out, '>', 'matches' or die $!;

while (my $line1 = <$fh1>) {

  seek $fh2, 0, 0;

  while (my $line2 = <$fh2>) {

    if ($line1 eq $line2) {
      print $out $line1;
      last;
    }
  }
}

Изменить

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

use strict;
use warnings;

open my $fh1, '<', 'file1' or die $!;
open my $fh2, '<', 'file2' or die $!;

open my $match, '>', 'matches' or die $!;
open my $nomatch, '>', 'nomatch' or die $!;

while (1) {

  my (@data1, @data2);

  for (1 .. 4) {
    my $line;
    $line = <$fh1>;
    push @data1, $line if defined $line;
    $line = <$fh2>;
    push @data2, $line if defined $line;
  }

  last unless @data1 == 4 and @data2 == 4;

  if ($data1[1] eq $data2[1]) {
    print $match @data2;
  }
  else {
    print $nomatch @data2;
  }
}
person Borodin    schedule 05.06.2012
comment
извините, нет... Я имел в виду следующее: каждая запись состоит из 4 строк.. строка 1 - заголовок, строка 2 - последовательность, строка 3 - разделитель, строка 4 - строка. Прочитать запись 1 из файла 1. Извлечь строку 2. Прочитать запись 1 из файла 2 проверить, является ли последовательность совпадением, если она сохраняется в файле, иначе сохраните ее в файле без совпадения (что означает чтение записи 2 из файла 1...) - person A14; 05.06.2012

Полный пример:

#!/usr/bin/env perl
use strict;
use warnings;

open F1, "<", "/path/1";
open F2, "<", "/path/2";

@a1 = <F1>;
@a2 = <F2>;

for (0..$#a1) {
    if ($a1[$_] eq $a2[$_]) {
        print "MATCH line [$_]\n";
    } else {
        print "DOESN'T MATCH line [$_]\n";
    }
}
person Gilles Quenot    schedule 05.06.2012