Найти слова в текстовом файле и получить соседний номер

У меня есть текстовый файл, который содержит слова и цифры.

Я хотел бы найти ключевое слово и, если файл содержит это слово, найти второе слово, если оно есть, я бы хотел извлечь число рядом со вторым словом.

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

Затем я хотел бы поместить числа в массив и отсортировать их численно.

У меня так далеко, но выход из массива 1 меняется, когда я присоединяю его к массиву 2 (некоторые числа дублируются). Мне нужен способ объединить обе операции.

my $filename;

my $filenamein = 'seq_id.txt';
open( my $fh, '<:encoding(UTF-8)', $filenamein )
    or die "Could not open file '$filename' $!";

while ( my $row = <$fh> ) {

    my $string = $row;

    my $startword = "16S ribosomal RNA";

    for ( $string =~ /$startword/ ) {

        my $word1 = "start:";
        $string =~ /$word1\s*?(\S+)/;
        my $next_word1 = $1;
        @w1 = ( $next_word1, );

        my $startword2 = "23S ribosomal RNA";

        for ( $string =~ /$startword2/ ) {

            my $word2 = "End";
            $string =~ /$word2\s*?(\S+)/;
            my $next_word2 = $1;
            @w2 = ( $next_word2, );
        }
    }

2 ответа

Большое спасибо за вашу помощь, очень ценю это. Я понял, что, вероятно, недостаточно знал, и попросил кого-то помочь!

Кажется, это работает для меня!

my $i;
my $filename;

my $filenamein = 'testin.txt';

open( my $fh, '<:encoding(UTF-8)', $filenamein )
    or die "Could not open file '$filename' $!";

while ( my $row = <$fh> ) {

    my $string = $row;

    my $startword = "16S ribosomal RNA";

    if ( $string =~ /$startword/ ) {

        my $word1 = "start:";
        $string =~ /$word1\s*?(\S+)/;
        my $next_word1 = $1;
        push( @w1, $next_word1 );

        print "Start @w1\n";

    }

    my $startword2 = "23S ribosomal RNA";

    if ( $string =~ /$startword2/ ) {

        my $word2 = "End";
        $string =~ /$word2\s*?(\S+)/;
        my $next_word2 = $1;
        push( @w2, $next_word2 );

        print "End @w2\n";

    }    # critical ender 2

}    #opener

Здесь есть несколько проблем с вашим кодом, это означает, что он почти наверняка не делает то, что вы думаете.

В первую очередь - включи use strict; а также use warnings;, Это предупредит вас о некоторых неприятных вещах.

Это например:

for ( $string =~ /$startword/ ) {

for повторяет список. Но $string =~ /$startword/ это не список Он вернет одно значение в зависимости от того, сработало совпадение или нет. В лучшем случае это действительно ужасный способ написания if заявление.

Вы также получили:

        my $word1 = "start:";
        $string =~ /$word1\s*?(\S+)/;
        my $next_word1 = $1;
        @w1 = ( $next_word1, )

То, что это делает, может быть уменьшено до:

my ( $word1 ) = ( $string =~ /start:\s*(\S+)/ );

Но тогда вы переписываете список @w1с одним элементом. Это то, что вы хотите сделать? Вы не используете @w1 где-нибудь еще.

То, что вы получили в настоящее время, возможно, может быть уменьшено до

use strict;
use warnings;

my $filenamein = 'seq_id.txt';
open( my $fh, '<:encoding(UTF-8)', $filenamein )
    or die "Could not open file '$filenamein' $!";

while ( my $row = <$fh> ) {
    if ( $row =~ m/16S ribosomal RNA/ ) {
        my ($next_word1) = ( $row =~ /start:\s*?(\S+)/ );
        my @w1 = ( $next_word1, );
    }

    if ( $row =~ /23S ribosomal RNA/ ) {
        my ($next_word2) = ( $row =~ /End\s*?(\S+)/ );
        my @w2 = ( $next_word2, );
    }
}

Вы также делаете что-то довольно странное с @w1 а также @w2 - это списки, но им всегда присваивается только один элемент. Это вряд ли то, что вы хотите сделать.

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