Как поменять имя в файле на другое в perl с хешем?

У меня есть файл, как это.

>;1;
AACTCTGGGACAATGGCACACGGGAAACAGATAATGAACGATCAGCACAGGGAACTAGCG
>;2;
AACTCTGGGACAATGGCACACGGGAAACAGATAATGAACGATCAGCACAGGGAACTAGCG
>;3;
AACTCTGGGACAATGGCACACGGGAAACAGATAATGAACGATCAGCACAGGGAACTAGCG

Я хотел бы изменить каждое число на соответствующую строку.

Я написал следующую программу на Perl, но я не знаю, что с ней не так.

%lista2 = (
    1  => "CAT00.3",
    2  => "CAT43.1",
    3  => "CAT40.3"
);

open(OA, ">file2.txt");

foreach $key ( keys %lista2 ) {

    open(SAL, "file.txt");

    while ( <SAL> ) {
        chomp;

        if( />/ ) {

            @w = split("\t");   
            $r = 0;
            s/\;//g;

            if ( /%lista2[i]/ ) {    
                print OA "$_ $lista2{$key}\n" ;
                $r = 1;
            }
        }
    }
}

close(SAL);
close(OA);

Я хочу получить это

>CAT00.3
AACTCTGGGACAATGGCACACGGGAAACAGATAATGAACGATCAGCACAGGGAACTAGCG
>CAT43.1
AACTCTGGGACAATGGCACACGGGAAACAGATAATGAACGATCAGCACAGGGAACTAGCG
>CAT40.3
AACTCTGGGACAATGGCACACGGGAAACAGATAATGAACGATCAGCACAGGGAACTAGCG

Но я не знаю, как это сделать.

1 ответ

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

Например, забавно, как вы можете иметь эти две строки

        if ( /%lista2[i]/ ) {    
            print OA "$_ $lista2{$key}\n" ;

имеет одну правильную попытку доступа к имеет значение ($lista2{$key}) и совершенно неверный (%lista2[i]) так близко друг к другу.

Тогда, так как вы печатаете только OA если ("/$lista2{$key}/"), вы бы полностью уничтожили все остальные строки в выводе. Ваш пример показывает, что вы этого не хотите.

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

И используйте, по крайней мере, некоторую базовую обработку ошибок. Проверить, если open провалился. Неправильное имя файла и программа завершается ошибкой без указания причины. Сделай свою жизнь проще.

Зачем использовать chomp() если позже вы добавите \n в любом случае, чтобы сделать вывод снова? Пропустить это

Я не знаю, как интерпретировать эти строки:

        @w = split("\t");   
        $r = 0;
        s/\;//g;

Это остатки? Они не делают ничего полезного.

И последнее, но не менее важное: use strict; и, возможно, use warnings; чтобы получить указатели на проблемные места.

Вот тот, который проходит ваш пример.

#!/usr/bin/perl

use strict;
use warnings;

my %lista2 =
(
  1  => "CAT00.3",
  2  => "CAT43.1",
  3  => "CAT40.3"
);

if (!open(OA, ">file2.txt")) {
 die($!);
}
if (!open(SAL, "file.txt")) {
  die($!);
}

foreach my $line (<SAL>) {
  foreach my $key (keys(%lista2)) {
    if ($line =~ s/^>;$key;$/>$lista2{$key}/) {
      last;
    }
  }
  print(OA $line);
}

close(SAL);
close(OA);

Фактически, в основном это можно упростить до замены шаблона. Нет расщепления или что-нибудь нужно. Но шаблоны могут быть запутанными, если вы новичок.

Я также поднял уровень многословия, чтобы прояснить ситуацию.

Другие вопросы по тегам