Как мне получить значения из последовательных строк в perl?

У меня есть эти данные ниже, называемые data.txt, я хочу получить четыре столбца из этих данных. Сначала я хочу получить категорию деградации, затем значение p, затем текст до и после Query:. Результат должен выглядеть так (показана только первая строка):

Degardome Category: 3  Degradome p-value: 0.0195958324320822   3' UGACGUUUCAGUUCCCAGUAU 5' Seq_3694_200

data.txt:

5' CCGGUAAGGUUAUGGGUCAUG 3' Transcript: Supercontig_2.8_1446328:1451-1471 Slice Site:1462
      |o||o||o| |||||||o
3' UGACGUUUCAGUUCCCAGUAU 5' Query: Seq_3694_200

SiteID: Supercontig_2.8_1446328:1462
MFE of perfect match: -36.10
MFE of this site: -23.60
MFEratio: 0.653739612188366
Allen et al. score: 7.5
Paired Regions (query5'-query3',transcript3'-transcript5')
    1-8,1471-1464
    10-18,1462-1454
Unpaired Regions (query5'-query3',transcript3'-transcript5')
    9-9,1463-1463   SIL: Symmetric internal loop
    19-21,1453-1451 UP3: Unpaired region at 3' of query

Degradome data file: /media/owner/newdrive/phasing/degradome/_degradome.20171210/bbduk_trimmed/merged_HV2.fasta_dd.txt
Degardome Category: 3
Degradome p-value: 0.0195958324320822
T-Plot file: T-plots-IGR/Seq_3694_200_Supercontig_2.8_1446328_1462_TPlot.pdf

Position    Reads   Category
1462    4   3   <<<<<<<<<<
2949    7   3
4179    517 0
---------------------------------------------------
---------------------------------------------------

5' GGUGAGGAGGGGGGUUUG-GUC 3' Transcript: Supercontig_2.8_1511075:1311-1331 Slice Site:1323
    | |||||oo||| |||o |||
3' AC-CUCCUUUCCCGAAAUACAG 5' Query: Seq_2299_664

SiteID: Supercontig_2.8_1511075:1323
MFE of perfect match: -37.90
MFE of this site: -25.30
MFEratio: 0.66754617414248
Allen et al. score: 8
Paired Regions (query5'-query3',transcript3'-transcript5')
    1-3,1331-1329
    5-8,1328-1325
    10-19,1323-1314
    20-20,1312-1312
Unpaired Regions (query5'-query3',transcript3'-transcript5')
    4-4,x-x BULq: Bulge on query side
    9-9,1324-1324   SIL: Symmetric internal loop
    x-x,1313-1313   BULt: Bulge on transcript side
    21-21,1311-1311 UP3: Unpaired region at 3' of query

Degradome data file: /media/owner/newdrive/phasing/degradome/_degradome.20171210/bbduk_trimmed/merged_HV2.fasta_dd.txt
Degardome Category: 4
Degradome p-value: 0.013385336399181

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

#!/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;
use Modern::Perl;

my word = "Query:";

my $filename = $ARGV[0];
open(INPUT_FILE, $filename);
while (<<>>) {
chomp;
my ($before, $after) = m/(.+)(?:\t\Q$word\E:\t)(.+)/i;
say "word: $word\tbefore: $before\tafter: $after";
}

@zdim Исправлено.

MAPK 26.10.2018 08:26

Размещено, но может возникнуть вопрос о точном формате данных (от которого зависит ответ, а некоторые из которых я предположил). Дай мне знать, как дела.

zdim 26.10.2018 08:39
2
2
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Известно, что интересующие фразы, Query:, затем Degardome Category: N, затем p-value, уникальны для контекста и мест, показанных в образце.

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

my $file = shift || die "Usage $0 file\n";

open my $fh, '<', $file  or die "Can't open $file: $!";

my (@res, @query, $category, $pvalue);

while (<$fh>) {
    next if not /\S/;

    if (/(.*?)\s+Query:\s+(.*)/) {
        @query = ($1, $2);
        next;
    }   

    if (/^\s*(Degardome Category:\s+[0-9]+)/) {
        $category = $1; 
    }   
    elsif (/^\s*(Degradome p-value:\s+[0-9.]+)/) {
        $pvalue = $1; 
        push @res, [$category, $pvalue, @query];
    }   
}

say "@$_" for @res;

Конец раздела определяется строкой p-value:, после чего мы добавляем к @res ссылку на массив со всеми необходимыми значениями, захваченными до этого момента.

Регулярное выражение во всем зависит от свойств данных, отображаемых в образце. Просмотрите и скорректируйте, если некоторые из моих предположений неверны.

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

Спасибо, но почему я получаю эту ошибку: perl grab_text_from_cleaveland_output.pl IGR-output.txt Modification of non-creatable array value attempted, subscript -1 at grab_text_from_cleaveland_output.pl line 22, <$fh> line 13

MAPK 26.10.2018 08:41

@MAPK Я только что скопировал свой код из этого сообщения и ваши образцы данных и получаю правильный результат? Добавляю вывод к ответу ...

zdim 26.10.2018 08:44

@MAPK Я понимаю, что упустил Category, добавив ... но он отлично работает для меня.

zdim 26.10.2018 08:45

@MAPK Понятно: в начале файла есть Query:, перед любым Degardome Category. Затем код совпадает с ним и пытается добавить его в массив ... которого еще нет. Что вы хотите от этой строки до того, как в файле будет обнаружен какой-либо Degardome Category?

zdim 26.10.2018 08:58

На самом деле он должен сначала получить значения этого типа: 3' UGACGUUUCAGUUCCCAGUAU 5' Query: Seq_3694_200, а затем Degradome Category.

MAPK 26.10.2018 08:59

Для данных моего примера будет только один выход.

MAPK 26.10.2018 09:02

@MAPK Ах. Отличается от опубликованных образцов данных (будьте осторожны с этим). ОК, исправлю. Для подтверждения: есть ли всегда сначала Query, затем Category и p-value? И вы по-прежнему хотите, чтобы результат был таким, как показано?

zdim 26.10.2018 09:03

Да, точно. Извините за путаницу.

MAPK 26.10.2018 09:03

@MAPK Также: есть ли другой способ или место, где могла бы быть фраза Query:? Я просмотрел файл, но он слишком велик, чтобы сканировать его целиком :). К тому же другие файлы могут немного отличаться ...

zdim 26.10.2018 09:05
Query:, Degradome Category и Degradome p-value: уникальны, чтобы составить одну строку в результате.
MAPK 26.10.2018 09:07

@MAPK Готово, обновленный ответ. В показанном вами файле есть 284 строки вывода. Категории чередуются от 0 до 4. p-значения меньше нуля, за исключением двух, которые больше 7, и одного больше 3.

zdim 26.10.2018 09:32

Большое спасибо. Я в основном работаю в R, и это было для меня совершенно внове. Очень помогло!

MAPK 26.10.2018 09:33

@MAPK Хорошо :) Помимо регулярного выражения, это чисто процедурно и будет очень похоже на любом языке, так что оно может быть полезно и в этом смысле.

zdim 26.10.2018 09:35

@MAPK Я бы посоветовал обновить образец данных, чтобы начать с Query: и т. д. - для тех, кто может прийти позже. Я тоже могу это сделать, если это не проблема (извлечь несколько строк из полного файла, который вы связали).

zdim 26.10.2018 09:35

Обновлено! Спасибо еще раз!

MAPK 26.10.2018 09:47

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