Скопировать несколько строк из одного файла в другой
Я хотел бы использовать 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?
2 ответа
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
Разрешить шаблонам соответствовать более чем одной строке.
Нет, 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
для второго шаблона это также будет включать в себя строку, содержащую второй шаблон.