Хобрук: Ваш путь к мастерству в программировании

Разделитель записей внутри разделителя записей

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

Я хочу выполнить цикл 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

    TTTATGC TTTATGG TTTATCC TTTATCG
    TTTATAA TTTATAA TTTATAT TTTATAT TTTATTA
    CTTGTAA 
File
    >TTTATGC
    TATAGCGCTTTATGCTAGCTAGC 
    >TTTATGG 
    TAGCTAGCTTTATGGGCTAGCTA 
    >TTTATCC
    GCTAGCTATTTATCCGCTAGCTA
    >TTTATCG
    TAGCTAGCTTTATCGCGTACGTA 
Sequences.fasta».

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


Ответы:


1

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

    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";
            }
        }
    }
06.06.2016
  • Есть ли способ изменить это, чтобы имя выходного файла включало количество строк в файле? Например, в выходном файле Clustered_Barcode_3_2_rows.fasta будет только 2 строки, а в выходном файле Clustered_Barcode_2_4_rows.fasta — 4 строки. Спасибо, 07.06.2016

  • 2

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

    #!/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;
    

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

    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 возвращаясь к началу); это остается читателю в качестве упражнения.)

    06.06.2016
  • Это прекрасно. Большое спасибо за ответ. Что касается прихлебывания, у меня будут тысячи строк текста, которые я буду вводить в код. Я буду делать это на сервере, и у меня может быть достаточно оперативной памяти, но может и не быть, в зависимости от моего набора данных. Есть ли эффективная с точки зрения памяти альтернатива slurp? Еще раз, я ОЧЕНЬ ценю ваш опыт. Спасибо. 06.06.2016
  • Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.