2016-06-06 2 views
2

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

Я хочу выполнить цикл while на отдельной вкладке с разделителем за раз в заданной строке элементов. Для каждой строки (строки) элементов, разделенных вкладкой, мне нужно распечатать результаты всех циклов while в уникальный файл. Позвольте пояснить следующие примеры.

Мой входной файл будет примерно следующим. Он будет называться «Clustered_Barcodes.txt»

TTTATGC TTTATGG TTTATCC TTTATCG 
    TTTATAA TTTATAA TTTATAT TTTATAT TTTATTA 
    CTTGTAA 

Мой Perl-код выглядит следующим образом:

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

    open(INFILE, "<", "Clustered_Barcodes.txt") or die $!; 

    my %hash = (
      "TTTATGC" => "TATAGCGCTTTATGCTAGCTAGC", 
      "TTTATGG" => "TAGCTAGCTTTATGGGCTAGCTA", 
      "TTTATCC" => "GCTAGCTATTTATCCGCTAGCTA", 
      "TTTATCG" => "TAGCTAGCTTTATCGCGTACGTA", 
      "TTTATAA" => "TAGCTAGCTTTATAATAGCTAGC", 
      "TTTATAA" => "ATCGATCGTTTATAACGATCGAT", 
      "TTTATAT" => "TCGATCGATTTATATTAGCTAGC", 
      "TTTATAT" => "TAGCTAGCTTTATATGCTAGCTA", 
      "TTTATTA" => "GCTAGCTATTTATTATAGCTAGC", 
      "CTTGTAA" => "ATCGATCGCTTGTAACGATTAGC", 
    ); 

    while(<INFILE>) { 
      $/ = "\n"; 
      my @lines = <INFILE>; 
      open my $out, '>', "Clustered_Barcode_$..fasta" or die $!; 
      foreach my $sequence (@lines){ 
        if (exists $hash{$sequence}){ 
        print $out ">$sequence\n$hash{$sequence}\n"; 
        } 
      } 
    } 

Мой желаемый результат будет три разных файла. Первый файл будет называться «Clustered_Barcode_1.fasta» и будет выглядеть следующим образом:

>TTTATGC 
    TATAGCGCTTTATGCTAGCTAGC 
    >TTTATGG 
    TAGCTAGCTTTATGGGCTAGCTA 
    >TTTATCC 
    GCTAGCTATTTATCCGCTAGCTA 
    >TTTATCG 
    TAGCTAGCTTTATCGCGTACGTA 

Обратите внимание, что это отформатированный так, что ключи предшествует морковь, а затем на следующей строке является больше связана последовательность (стоимость). Этот файл включает в себя все последовательности в первой строке Clustered_Barcodes.txt

Мой третий файл должен называться «Clustered_Barcode_3.fasta» и выглядит следующим образом:

>CTTGTAA 
    ATCGATCGCTTGTAACGATTAGC 

Когда я запускаю мой код, только берет вторую и третью строки последовательностей во входном файле. Как начать с первой строки (избавляясь от требования \ n для разделителя записей)? Как я могу обрабатывать каждый элемент одновременно, а затем печатать результаты результатов линии в один файл? Кроме того, если есть способ включить количество последовательностей в имя файла, это будет здорово. Это поможет мне позже организовать файлы по размеру. Например, имя может быть чем-то вроде «Clusterd_Barcodes_1_File_3_Sequences.fasta».

Спасибо всем.

ответ

2

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

while(my $line = <INFILE>) { 
     chomp $line; 
     open my $out, '>', "Clustered_Barcode_$..fasta" or die $!; 
     foreach my $sequence (split /\t/, $line){ 
      if (exists $hash{$sequence}){ 
       print $out ">$sequence\n$hash{$sequence}\n"; 
      } 
     } 
    } 
+0

Есть ли способ изменить это, так что имя выходного файла включает в себя количество строк в файле? Например, в выходном файле «Clustered_Barcode_3_2_rows.fasta» будет только 2 строки, и в выходном файле «Clustered_Barcode_2_4_rows.fasta» будет 4 строки. Благодаря, – Rob

3

ОК, так вот один из способов сделать это:

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

Стандартная преамбулу.

my %hash = (
    "TTTATGC" => "TATAGCGCTTTATGCTAGCTAGC", 
    "TTTATGG" => "TAGCTAGCTTTATGGGCTAGCTA", 
    "TTTATCC" => "GCTAGCTATTTATCCGCTAGCTA", 
    "TTTATCG" => "TAGCTAGCTTTATCGCGTACGTA", 
    "TTTATAA" => "TAGCTAGCTTTATAATAGCTAGC", 
    "TTTATAA" => "ATCGATCGTTTATAACGATCGAT", 
    "TTTATAT" => "TCGATCGATTTATATTAGCTAGC", 
    "TTTATAT" => "TAGCTAGCTTTATATGCTAGCTA", 
    "TTTATTA" => "GCTAGCTATTTATTATAGCTAGC", 
    "CTTGTAA" => "ATCGATCGCTTGTAACGATTAGC", 
); 

Настроить хэш последовательностей.

my $infile = 'Clustered_Barcodes.txt'; 
open my $infh, '<', $infile or die "$0: $infile: $!\n"; 

Открыть файл для чтения.

chomp(my @rows = readline $infh); 
my $row_count = @rows; 

Сверните все строки в память, чтобы получить количество последовательностей. Если у вас слишком много последовательностей, этот подход не будет работать (потому что у вас закончится нехватка памяти (но это зависит от того, сколько у вас RAM)).

my $i = 1; 
for my $row (@rows) { 

Петля над линиями.

my @fields = split /\t/, $row; 

Разделить каждую строку на поля, разделенные вкладками.

my $outfile = "Clustered_Barcodes_${i}_File_${row_count}_Sequences.fasta"; 
    $i++; 
    open my $outfh, '>', $outfile or die "$0: $outfile: $!\n"; 

Открытый текущий выходной файл и счетчик приращений.

for my $field (@fields) { 
     print $outfh ">$field\n$hash{$field}\n" if exists $hash{$field}; 
    } 

Напишите каждое поле (и его отображение) в outfile.

} 

И все готово. Основное отличие от вашего исходного кода - использовать split /\t/ и foreach, чтобы пересечь поля внутри строки.


Мы можем сделать это без прихлебывая, тоже:

while (my $row = readline $infh) { 
    chomp $row; 

петлю на линии, один за другим. Это заменяет 4 строки от chomp(my @rows = readline $infh); до for my $row (@rows) {.

Но теперь мы потеряли $i и $row_count переменные, так что мы должны изменить инициализацию $outfile:

my $outfile = "Clustered_Barcodes_$..fasta"; 

Это должно быть все необходимые изменения. (Вы можете получить $row_count обратно в этом случае, читая $infh дважды (первый раз только для подсчета, то seek ING обратно к началу), это остается в качестве упражнения для читателя.)

+0

Это замечательно. Большое спасибо за ответ. Что касается slurping, у меня будет тысячи строк текста для подачи кода. Я буду делать это на сервере и, возможно, хватит ОЗУ, но я не могу, в зависимости от моего набора данных. Есть ли эффективная альтернатива памяти для slurp? Опять же, я ДЕЙСТВИТЕЛЬНО ценю ваш опыт. Благодарю. – Rob

+0

@Rob Я обновил свой ответ. – melpomene