скопировать несколько строк из одного файла в другой

скопировать несколько строк из одного файла в другой

Я хотел бы использовать 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. Вместо этого, поскольку вы знаете, что последовательности белков всегда будут в ВЕРХНЕМ РЕГИСТРЕ и будут заканчиваться на ", вы можете сопоставить это:

  1. sed

    sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
    

    Шаблон означает «напечатать все строки между и » sed. Он подавляет обычный вывод, поэтому печатаются только запрошенные строки. Обратите внимание, что of необходимо экранировать ( ), поскольку является частью оператора сопоставления. Второй шаблон немного сложнее: он ищет 0 или более пробелов в начале строки ( ), затем одну или более заглавных букв, за которыми следует двойная кавычка ( ), а затем 0 или более пробельных символов до конца строки ( )./foo/,/bar/{p}foobar-n//protein_id=\//^\s*[[:upper:]]"\s*$

  2. Перл

    perl -ne 'print if m#/protein_id=# ... m#[A-Z]+"\s*$#' file.flat 
    

    Здесь та же идея: ...оператор указывает диапазон, и печатаются линии между двумя шаблонами.

  3. awk

    awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat 
    

    Здесь мы устанавливаем переменную aв значение 1, если строка соответствует первому шаблону, и в значение , 0если она соответствует последнему. Затем мы говорим, awkчто нужно вывести if ais 1. Поскольку printis вызывается до того, aкак установлено 0для второго шаблона, это также включит строку, содержащую второй шаблон.

Связанный контент