Отфильтровать (или «вырезать») столбец, который начинается с «OS = ab c» - PullRequest
1 голос
/ 20 апреля 2020

Мой файл .fasta состоит из этого повторяющегося шаблона.

>sp|P20855|HBB_CTEGU Hemoglobin subunit beta OS=Ctenodactylus gundi OX=10166 GN=HBB PE=1 SV=1
asdfaasdfaasdfasdfa
>sp|Q00812|TRHBN_NOSCO Group 1 truncated hemoglobin GlbN OS=Nostoc commune OX=1178 GN=glbN PE=3 SV=1
asdfadfasdfaasdfasdfasdfasd
>sp|P02197|MYG_CHICK Myoglobin OS=Gallus gallus OX=9031 GN=MB PE=1 SV=4
aafdsdfasdfasdfa

Я хочу отфильтровать только строки, содержащие '>', ТО отфильтровать строку после 'OS =' и до 'OX = ', (пример line1 = Ctenodactylus gundi)

Первая часть ('> ') достаточно проста:

grep '>' my.fasta | cut -d " " -f 3 >> species.txt

Проблема в том, что количество полей не является постоянным ДО ДО' ОС знак равно

Но число столбцов / полей между 'OS =' и 'OX =' равно 2.

Ответы [ 4 ]

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

Вы можете использовать опцию -P, чтобы включить сопоставление регулярных выражений на основе PCRE, и использовать шаблоны обхода, чтобы убедиться, что соответствие заключено между OS= и OX=:

grep '>' my.fasta | grep -oP '(?<=OS=).*(?=OX=)'

Обратите внимание, что опция -P доступна только для версии GNU grep, которая может быть недоступна по умолчанию в некоторых средах.

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

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

awk '/^>/ && match($0,/OS=.*OX=/){print substr($0,RSTART+3,RLENGTH-6)}' Input_file

Вывод будет следующим.

Ctenodactylus gundi
Nostoc commune
Gallus gallus

Объяснение: Добавление подробного пояснения к приведенному выше коду.

awk '                                    ##Starting awk program from here.
/^>/ && match($0,/OS=.*OX=/){            ##Checking condition if line starts from > AND matches regex OS=,*OX= means match from OS= till OX= in each line, if both conditions are TRUE.
  print substr($0,RSTART+3,RLENGTH-6)    ##Then print sub string of current line, whose starting point is RSTART+3 to till RLENGTH-6 of current line.
}
' Input_file                             ##Mentioning Input_file name here.
1 голос
/ 20 апреля 2020

sed решение:

$ sed -nE '/>/ s/^.*OS=(.*) OX=.*$/\1/p' .fasta
Ctenodactylus gundi
Nostoc commune
Gallus gallus

-n, чтобы пространство шаблона не печаталось без запроса; -E (расширенные регулярные выражения), чтобы мы могли использовать подвыражения и обратные ссылки. Флаг p команды s означает «печать пространства шаблона».

Регулярное выражение должно соответствовать всей строке, выделяя в подвыражении фрагмент, который мы должны извлечь. Я предположил, что OX предшествует ровно один пробел, который не должен появляться в выходных данных; это можно скорректировать, если / при необходимости.

Предполагается, что все строки, начинающиеся с >, будут иметь OS= ... фрагмент , сразу , за которым следует OX= ... фрагмент; если нет, то его можно добавить в фильтр />/ перед командой s. (Между прочим - может ли быть некоторый OT= ... фрагмент между OS=... и OX= ...?)

Вопрос, хотя - вы бы не включили какой-то идентификатор (возможно, часть «метка» в начале каждой строки) для каждой строки вывода? У вас есть запрошенные фрагменты, но знаете ли вы, где находится каждый из них?

1 голос
/ 20 апреля 2020

Использование любого awk в любой оболочке на каждом UNIX поле:

$ awk -F' O[SX]=' '/^>/{print $2}' file
Ctenodactylus gundi
Nostoc commune
Gallus gallus
...