Как удалить новые строки массива и добавить элемент в начале его в Perl? - PullRequest
0 голосов
/ 28 апреля 2020

Прежде всего я должен извиниться за редактирование моего первоначального сообщения. Но после того как я предоставил свой код, я сделал вопрос нечетким.

Итак, у меня есть этот массив (@start_cod), содержащий строки, разделенные / n следующим образом:

print @start_cod;

tatatattataattatatttat
    cacacacaacaccacaac
    aaaaaaaaaaaaaaa

Мне нужно удалить символы новой строки и добавить "> текст" ТОЛЬКО в начало массива следующим образом:

 >text
   tatatattataattatatttatcacacacaacaccacaacaaaaaaaaaaaaaaa

Я пытался:

 s/\s+\z//  for @start_cod;                     
    print  ">text@start_cod";

Я пытался также с chomp

chomp @start_cod;                      
 print  ">text@start_cod";

и

my @start_cod = split("\n",$start_cod); 
  $start_cod = join("",@start_cod);
      print  ">text$start_cod";

но я получаю

aaaaaaaaaaaaaaaaaaa>textcacacacacaacaccacaac>textaattatatattataattatatttat

Любые предложения о том, как справиться с этим в Perl Программирование?

Вот мой код, который работает на 100%.

 #!/usr/bin/perl

    use strict;
    use warnings;
    use feature 'say';


    my %alliloux =();

    $/="\n>";

    while (<>) {
        s/>//g;
        my ($onoma, @seq) = split (/\n/, $_);
        my ($sp, $head) = split (/\./, $onoma);
        push @{ $alliloux{$sp} }, join "\n", ">$onoma", @seq;

               }

    foreach my $sp (keys %alliloux) {
                   chomp $sp; 
          my ($head, $dna) = split(/\t/, $sp);  
          my @start_cod = substr($dna, 3);


    say  @start_cod;

Входной файл:

>name   aaaaaaaaaaaaaaaaaa
>name2  acacacacacaacaccacaac
>namex  aattatatattataattatatttat

вывод после Perl run

tatatattataattatatttat
cacacacaacaccacaac
aaaaaaaaaaaaaaa

Желаемый вывод:

>text
 tatatattataattatatttatcacacacaacaccacaacaaaaaaaaaaaaaaa

Ответы [ 3 ]

2 голосов
/ 28 апреля 2020

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

use strict;
use warnings;

my @start_cod = (
    'aaaaaaaaaaaaaaaaaa',
    'acacacacacaacaccacaac',
    'aattatatattataattatatttat',
);
print ">text\n", @start_cod, "\n";

print сначала печатает "> текст" и новую строку один раз, затем вы получаете элементы @start_cod на строка, а последняя "\n" обеспечивает наличие новой строки после последнего элемента.

Вывод:

>text
aaaaaaaaaaaaaaaaaaacacacacacaacaccacaacaattatatattataattatatttat
0 голосов
/ 29 апреля 2020

Возможно, вы захотите увидеть Читать FASTA в Ha sh. Это та же проблема, и она очень близка к коду, который я написал до того, как прочитал. Кроме того, на CPAN есть модули, которые могут обрабатывать FASTA .


Я думаю, что вы хотите объединить последовательности, начинающиеся с одного и того же имени, без учета чисел. Последовательности не должны иметь внутренних пробелов. В своем коде вы постоянно добавляете пробелы. Вы даже присоединитесь к новой строке. Итак, вы go к доктору и говорите: «Моя рука болит, когда я делаю это», а доктор говорит: «Так не делайте этого». :)

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

Короче, прочитайте строку и удалите новую строку в конце. Это один из источников вашей новой строки. Затем извлеките последовательность и объедините ее с предыдущей последовательностью. Когда вы join с новыми строками, вы добавляете новые строки. Так что не делайте этого:

use v5.14;
use warnings;
use Data::Dumper;

my %alliloux = ();

while (<DATA>) {
    chomp;  # get rid of that newline!
    s/>//g;

    # now split on whitespace, but only up to two parts.
    # There's no array here.
    my( $name, $seq ) = split /\s+/, $_, 2;

    # remove the numbers at the end to get the prefix of the
    # name.
    my $prefix = $name =~ s/\d+\z//r;

    # append the current sequence for this prefix to what we
    # have already seen.f
    $alliloux{$prefix} .= $seq;
}

say Dumper( \%alliloux );
foreach my $base ( keys %alliloux ) {
    say ">text $alliloux{$base}";
    }

__DATA__
>name  aaa
>name2  cccc
>name99 aattaatt

Вам не нужен промежуточный массив. Вы можете создать свою строку как вы go. Вам не нужно иметь все части, прежде чем вы это сделаете.

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

while (<DATA>) {
    chomp;  # get rid of that newline!
    s/>//g;

    my( $name, $seq ) = split /\s+/, $_, 2;

    say "Name: <$name>";
    say "Seq: <$seq>"
}

Затем добавьте еще один шаг и убедитесь, что он работает:

while (<DATA>) {
    chomp;  # get rid of that newline!
    s/>//g;

    my( $name, $seq ) = split /\s+/, $_, 2;

    say "Name: <$name>";
    say "Seq: <$seq>"

    my $prefix = $name =~ s/\d+\z//r;
    say "Prefix: <$prefix>";
}

Повторите этот процесс для каждого шага. Затем, когда вы пришли с вопросом, вы определили точку, где вещи расходятся. Вот та же техника в вашей программе:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

while (<DATA>) {
    s/>//g;
    my ($onoma, @seq) = split (/\n/, $_);
    say "Onoma: <$onoma>";
}

__DATA__
>name  aaa
>name2  cccc
>name99 aattaatt

Вывод показывает, что у вас никогда ничего не было в @seq. Вы разделяете новую строку, но если вы не изменили конец строки по умолчанию, вы получите только новую строку в конце:

Onoma: <name  aaa>
Onoma: <name2  cccc>
Onoma: <name99 aattaatt>

Теперь в @seq нет ничего, поэтому такая строка join "\n", ">$onoma", @seq; на самом деле просто join "\n", ">$onoma". Вы могли бы увидеть это с небольшой проверкой.

0 голосов
/ 28 апреля 2020

В описании отсутствует ясность проблемы.

При просмотре желаемого результата на ум приходит следующий код. Пожалуйста, посмотрите, делает ли он то, что вы искали.

Даже глядя на ваш код, не ясно, что вы пытаетесь сделать - какая-то часть кода не имеет особого смысла.

use strict;
use warnings;
use feature 'say';

my @start_cod;

while( <DATA> ) {
    chomp;
    next unless />\s?name.?\s+(.*)/;
    push @start_cod, $1;
}

print ">text\n " . join('',@start_cod);

__DATA__
>name  aaaaaaaaaaaaaaaaaa
>name2  acacacacacaacaccacaac
.
.
.
> namex aattatatattataattatatttat
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...