Я хотел бы использовать grep для копирования из одного файла в другой всех строк, которые находятся между строками /protein_id=
, до конца показанной последовательности белка. Например, из этого ввода:
CDS 448..1269
/gene="nptII"
/note="neomycin phosphotransferase II"
/codon_start=1
/product="kanamycin resistance protein"
/protein_id="AAQ05967.1"
/db_xref="GI:33320494"
/translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
regulatory 1443..2148
я хотел бы получить этот вывод:
/protein_id="AAQ05967.1"
/db_xref="GI:33320494"
/translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
Обратите внимание, что вход может отличаться тем, что строка, начинающаяся с regulatory
, может быть заменена на что-то другое. Неизменным является то, что последовательность дана заглавными буквами и заканчивается знаком "
. Возможно ли это с помощью grep?
pcregrep
- это утилита grep, которая использует регулярные выражения, совместимые с Perl 5. Регулярные выражения в стиле Perl имеют много полезных функций, которых нет в стандартных POSIX. Это в основном то же самое, что и grep, но с другим синтаксисом регулярного выражения.
sudo apt-get install pcregrep
pcregrep -M .*'/protein_id=.*(\n|.)*\"' path/to/input-file
/ protein_id
- это начальный критерий поиска, а «
- конечный критерий поиска.
Вот обобщенный пример команды для выполнения многострочного поиска для всех строк, которые находятся между начальный термин поиска и конечный термин поиска:
pcregrep -M .*'START-SEARCH-TERM.*(\n|.)*END-SEARCH-TERM' path/to/SOURCE-FILE >> path/to/DESTINATION-FILE
где:
-M, --multiline
Разрешить шаблонам соответствовать более чем одной строке. Нет, grep
не может соответствовать через несколько строк. Вы могли сделать это с pcregrep
как показано @karel, но не чистый grep
. Вместо этого так как Вы знаете, что последовательности белка всегда будут в ВЕРХНЕМ РЕГИСТРЕ и закончатся "
, Вы могли соответствовать этому:
sed
sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
sed
шаблон /foo/,/bar/{p}
означает, "печатают все строки между foo
и bar
. -n
подавляет нормальный вывод поэтому, только строки, которые требуют, печатаются. Обратите внимание что /
из /protein_id=
потребности, которых оставят (\/
) потому что /
часть оператора соответствия. Второй шаблон немного более сложен, он ищет 0 или больше пробелов в начале строки (^\s*
), затем одна или несколько прописных букв, сопровождаемых двойной кавычкой ([[:upper:]]"
) и затем 0 или больше пробельных символов до конца строки (\s*$
).
Perl
perl -ne 'print if m#/protein_id=# ... m#[A-Z]+"\s*$#' file.flat
Та же идея здесь, ...
оператор указывает диапазон, и строки между этими двумя шаблонами печатаются.
awk
awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat
Здесь, мы устанавливаем переменную a
кому: 1
если строка соответствует первому шаблону и к 0
если это соответствует последнему. Затем говорим мы awk
распечатать если a
1
. Начиная с print
назван прежде a
установлен на 0
для второго шаблона это будет включать строку, содержащую второй шаблон также.