Я хотел бы использовать 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?
решение1
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
где:
- SOURCE-FILE — файл, содержащий ваши данные
- DESTINATION-FILE — файл, куда будут скопированы результаты.
- START-SEARCH-TERM — начальный поисковый термин
- END-SEARCH-TERM — конечный поисковый термин
-M, --multiline
Разрешить шаблонам соответствовать более чем одной строке.
решение2
Нет, grep
нельзя сопоставить по нескольким строкам. Вы можете сделать это с помощью, pcregrep
как показано @karel, но не pure grep
. Вместо этого, поскольку вы знаете, что последовательности белков всегда будут в ВЕРХНЕМ РЕГИСТРЕ и будут заканчиваться на "
, вы можете сопоставить это:
sed
sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
Шаблон означает «напечатать все строки между и »
sed
. Он подавляет обычный вывод, поэтому печатаются только запрошенные строки. Обратите внимание, что of необходимо экранировать ( ), поскольку является частью оператора сопоставления. Второй шаблон немного сложнее: он ищет 0 или более пробелов в начале строки ( ), затем одну или более заглавных букв, за которыми следует двойная кавычка ( ), а затем 0 или более пробельных символов до конца строки ( )./foo/,/bar/{p}
foo
bar
-n
/
/protein_id=
\/
/
^\s*
[[:upper:]]"
\s*$
Перл
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
что нужно вывести ifa
is1
. Посколькуprint
is вызывается до того,a
как установлено0
для второго шаблона, это также включит строку, содержащую второй шаблон.