Печать символов перед соответствием рисунку - PullRequest
0 голосов
/ 19 февраля 2011

Ниже приведена комбинация команд awk

awk '
    {if ($0~/>/) {head=$0;getline}
    {if($0~/pattern/) print head"\n"$0}}' filename1 | 
awk 
   'BEGIN  {pos=0;char=0}
    {if($0~/>/) head=$0;getline}
    {pos=0; 
     if($0~/pattern/)
       {pos=match($0,/pattern/);char=substr($0,pos,55)} 
     print head"\n"char}'

Над одним работает отлично, я хотел захватить 55 символов после определения шаблона "AATTGGCC". Проблема в том, как я могу получить префикс в 55 символов для соответствующего шаблона (55 слов перед соответствующим шаблоном). Да, я могу написать все это в perl, но, поскольку у меня есть вышеперечисленное в awk, было интересно, могу ли я как-то изменить его.

Спасибо

Ответы [ 4 ]

0 голосов
/ 19 февраля 2011

Спасибо всем за ваши предложения. Что касается формата кода awk, я не выполнял его ни в каком сценарии, ни в чем-либо другом. Все это было в командной строке и, следовательно, так много в "трубе" вывода. Но я понимаю и постараюсь писать коды в правильном формате всякий раз, когда обращаюсь за помощью.

Я обнаружил, что RSTART в awk - это переменная, которая отслеживает соответствие шаблона, поэтому я смог использовать его следующим образом (это только часть реальной команды).

awk 'BEGIN{pos=0;char=0}{if($0~/>/) head=$0;getline} {pos=0;if($0~/pattern/) {match($0,/pattern/);char=substr($0,RSTART-47,47)}print head"\n"char}'.

Возвращает 47 символов обратно из соответствующего шаблона и печатает его.

0 голосов
/ 19 февраля 2011

Вот демонстрация способа печати некоторых символов, предшествующих шаблону:

echo 'abcdefghijklmnopqrstuvwxyz' | 
    awk 'BEGIN {pat = "jkl"; n = 5} 
        pat {
            i = index($0,pat);
            print substr($0, i-n, n + length(pat))
        }'

Вывод (пять символов перед "jkl" и "jkl"):

efghijkl

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

Для чего это стоит, вот упрощенная версия вашего скрипта. Он может работать неправильно, но он более читабелен и более AWKish. Я ничего не сделал с ним, чтобы попытаться заставить его выполнять необходимые функции, и я не проверял его.

awk '

    />/ {head = $0; getline}

    /pattern/ print head "\n" $0

    ' filename1 | 
awk '

    BEGIN  {pos = 0; char = 0}

    />/) {head = $0; getline}
    {
        pos = 0; 
        if ($0 ~ /pattern/) {
            pos = match($0, /pattern/); char = substr($0, pos, 55)
        } 
        print head "\n" char
    }'
0 голосов
/ 19 февраля 2011

Без какого-либо примера ввода сложно протестировать, но я считаю, что ваш очень похожий на C awk может быть уменьшен до:

awk -v pattern="abcd_or_whatever" -v n=55'
    />/ {head=$0; next}
    pos = match($0, pattern) {print head "\n" substr($0, pos, n)} 
'

и чтобы получить 55 символов до совпадения, вам просто нужно изменить аргументы substr на substr($0, pos-n, n)

0 голосов
/ 19 февраля 2011

Это немного грубая сила, но вы можете использовать шаблон, который имеет 55 периодов до AATTGGCC

Например:

/.......................................................AATTGGCC/ {print substr(%$0,1,55)}

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

Но лучше всего было бы использовать Python и библиотеку , такую ​​как pygep , потому что Python широко используется в биоинформатике.

...