grep: объединить отрицательное совпадение с после (поиск последовательностей белков, не содержащих фрагмент слова) - PullRequest
1 голос
/ 18 июня 2020

У меня есть последовательность fasta, и я хочу отфильтровать все те, у которых есть слово Fragment в заголовке.

Я думал, что могу использовать grep с -A 1 (потому что последовательность белка всегда находится в одной строке) с -i (в случае, если фрагмент не пишется с заглавной буквы) и использовать это с -v, но каким-то образом инвертирование результата не работает должным образом.

>tr|A0A534K2W8|A0A534K2W8_9EURY Epoxide hydrolase 1 (Fragment) OS=Euryarchaeota archaeon OX=2026739 GN=E6K10_05355 PE=4 SV=1 
MSNTPDFNRR...
>tr|A0A4S3JUN3|A0A4S3JUN3_9EURO AB hydrolase-1 domain-containing protein OS=Aspergillus tanneri OX=1220188 GN=ATNIH1004_010243 PE=4 SV=1
MRDKYTPATL...
>tr|B1AQP8|B1AQP8_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|B1AQP9|B1AQP9_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|Q6FGZ3|Q6FGZ3_HUMAN EPHX1 protein (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=2 SV=1
MWLEILLTSV...
>tr|A0A2G8L4U1|A0A2G8L4U1_STIJA Putative epoxide hydrolase 1-like OS=Stichopus japonicus OX=307972 GN=BSL78_07808 PE=4 SV=1
MVHGWPGSFY...

Если я хочу сохранить последовательности с фрагментом , он работает нормально

grep -i "fragment" -A 1 test.fasta                                             
>tr|A0A534K2W8|A0A534K2W8_9EURY Epoxide hydrolase 1 (Fragment) OS=Euryarchaeota archaeon OX=2026739 GN=E6K10_05355 PE=4 SV=1 
MSNTPDFNRR...
--
>tr|B1AQP8|B1AQP8_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|B1AQP9|B1AQP9_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|Q6FGZ3|Q6FGZ3_HUMAN EPHX1 protein (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=2 SV=1
MWLEILLTSV...

, но если я хочу инвертировать совпадение, это результат.

grep -i "fragment" -A 1 -v test.fasta
MSNTPDFNRR...
>tr|A0A4S3JUN3|A0A4S3JUN3_9EURO AB hydrolase-1 domain-containing protein OS=Aspergillus tanneri OX=1220188 GN=ATNIH1004_010243 PE=4 SV=1
MRDKYTPATL...
>tr|B1AQP8|B1AQP8_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|B1AQP9|B1AQP9_HUMAN Epoxide hydrolase 1 (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=1 SV=1
MWLEILLTSV...
>tr|Q6FGZ3|Q6FGZ3_HUMAN EPHX1 protein (Fragment) OS=Homo sapiens OX=9606 GN=EPHX1 PE=2 SV=1
MWLEILLTSV...
>tr|A0A2G8L4U1|A0A2G8L4U1_STIJA Putative epoxide hydrolase 1-like OS=Stichopus japonicus OX=307972 GN=BSL78_07808 PE=4 SV=1
MVHGWPGSFY...

Есть идеи, где я go ошибаюсь?

1 Ответ

1 голос
/ 18 июня 2020

Проблема в том, что -v нельзя использовать с переключателями контекста. Если у вас есть GNU grep с PCRE, вы можете использовать сложное регулярное выражение:

grep --no-group-separator -xiP -A 1 '>((?!fragment).)+'

Обратите внимание на использование --no-group-separator, чтобы избежать -- между разными совпадениями. -P включает PCRE. -x обеспечивает соответствие всей строки. >((?!fragment).)+ гарантирует, что fragment отсутствует в строках, начинающихся с > (см. Альтернативные утверждения с переменной длиной назад для регулярных выражений для получения дополнительной информации)


Но для таких случаев лучше использовать awk:

# with GNU awk
awk -v IGNORECASE=1 '/^>/ && !/fragment/{f=2} f && f--'
# any awk
awk '/^>/ && tolower($0) !~ /fragment/{f=2} f && f--'

Здесь f=2 на 1 больше, чем количество строк, которое вам нужно после совпадения. /^>/ && !/fragment/ будет соответствовать только строкам, начинающимся с > и НЕ содержащим fragment

См. Также строки вокруг совпадающего регулярного выражения для получения дополнительных таких примеров.

...