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, извличам го и получавам последователността. след това прочетете първия запис от файл 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