Как напечатать специальную строку?

У меня есть файл со следующим содержимым:

NC_014378.1 Protein Homology    CDS 192004  192117  .   +   0   ID=cds185;Parent=gene211;Dbxref=Genbank:WP_013277182.1;Name=WP_013277182.1;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:WP_005487032.1;product=50S ribosomal protein L36;protein_id=WP_013277182.1;transl_table=11
NC_014378.1 Protein Homology    CDS 1753871 1754437 .   +   0   ID=cds1636;Parent=gene1718;Dbxref=Genbank;Name=NP_013278608.1;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:NP_013278608.1;product=hypothetical protein;protein_id=NP_013278608.1;transl_table=11
NC_014378.1 Protein Homology    CDS 233759  235705  .   +   0   ID=cds226;Parent=gene252;Dbxref=Genbank;Name=RCSM;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:YP_013277222.1;product=methyl-accepting chemotaxis;transl_table=11
NC_014378.1 Protein Homology    CDS 486732  488687  .   +   0   ID=cds446;Parent=gene486;Dbxref=Genbank:WP_013277438.1;Name=WP_013277438.1;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:WP_013277438.1;product=methyl-accepting chemotaxis protein;protein_id=WP_013277438.1;transl_table=11

Я хочу получить следующий вывод

192004  192117  +  WP_013277182.1
1753871 1754437  +  NP_013278608.1
233759  235705  +  YP_013277222.1
486732  488687  +  WP_013277438.1

Какая команда unix будет использоваться.

-1
задан 03.05.2019, 15:22

3 ответа

С GNU awk:

awk '{print $5,$6,$8,gensub(/.*([NWY]P_[^;]+).*/,"\\1",1)}'

Это печатает (разделенные пробелами) поля 5, 6, 8 и первую строку, начинающуюся с «N», «W» или «Y», а затем на «P_» до следующей точки с запятой от текущей строки.

Если вы хотите другой разделитель O utput F ield S , измените переменную OFS в блоке BEGIN, например, для двух пробелов используйте:

awk 'BEGIN{OFS="  "}{print $5,$6,$8,gensub(/.*([NWY]P_[^;]+).*/,"\\1",1)}'

Если вы хотите выровнять значения OFS="\t" для столбцов, разделенных табуляцией, это хороший выбор.

Если вы не можете использовать GNU awk, вы можете использовать функции match() и substr() для замены gensub():

awk 'match([112],/[NWY]P_[^;]+/){print $5,$6,$8,substr([112],RSTART,RLENGTH)}'

Пояснения

    [ 1127] print $5,$6,$8 - вывести эти поля, разделенные OFS
  • gensub(/.*([NWY]P_[^;]+).*/,"\\1",1) - во всей текущей строке (по умолчанию) заменить .*([NWY]P_[^;]+).* на то, что сохранено в группе 1 ("\\1"), один раз. .*([NWY]P_[^;]+).* соответствует всей строке, сохраняя первую строку, состоящую из «N», «W» или «Y», за которой следует «P_», и, по крайней мере, один символ, который не является «;» ([^;]+, поскольку регулярные выражения являются жадными, соответствует всему до первой точки с запятой) как группа.
  • match([1116],/[NWY]P_[^;]+/) - поиск в [1117] (= всей строке) первого совпадения [NWY]P_[^;]+ (см. Выше) и установить переменную RSTART в ее индекс, а переменную RLENGTH в ее счетчик символов. [тысяча сто двадцать девять]
  • substr([1121],RSTART,RLENGTH) - из [1122] извлечь строку, начинающуюся с индекса RSTART с длиной RLENGTH

Пример выполнения

$ cat YP 
NC_014378.1 Protein Homology    CDS 192004  192117  .   +   0   ID=cds185;Parent=gene211;Dbxref=Genbank:WP_013277182.1;Name=WP_013277182.1;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:WP_005487032.1;product=50S ribosomal protein L36;protein_id=WP_013277182.1;transl_table=11
NC_014378.1 Protein Homology    CDS 1753871 1754437 .   +   0   ID=cds1636;Parent=gene1718;Dbxref=Genbank;Name=NP_013278608.1;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:NP_013278608.1;product=hypothetical protein;protein_id=NP_013278608.1;transl_table=11
NC_014378.1 Protein Homology    CDS 233759  235705  .   +   0   ID=cds226;Parent=gene252;Dbxref=Genbank;Name=RCSM;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:YP_013277222.1;product=methyl-accepting chemotaxis;transl_table=11
NC_014378.1 Protein Homology    CDS 486732  488687  .   +   0   ID=cds446;Parent=gene486;Dbxref=Genbank:WP_013277438.1;Name=WP_013277438.1;gbkey=CDS;inference=COORDINATES: similar to AA sequence:RefSeq:WP_013277438.1;product=methyl-accepting chemotaxis protein;protein_id=WP_013277438.1;transl_table=11
$ <YP awk '{print $5,$6,$8,gensub(/.*([NWY]P_[^;]+).*/,"\\1",1)}'
192004 192117 + WP_013277182.1
1753871 1754437 + NP_013278608.1
233759 235705 + YP_013277222.1
486732 488687 + WP_013277438.1
2
ответ дан 25.10.2019, 12:33

С помощью sed:

sed -E 's/.*CDS //;s/ *\. //;s/ 0.*([NWY]P_[^;]+).*/\1/'

Пояснения

  • s/.*CDS // - s заменить строку «CDS» и все (в текущей обрабатываемой строке) перед это без ничего - это удаляет начало строки
  • s/ *\. // - заменяет ноль или более пробелов, за которыми следует точка, за которой ничего не стоит - это удаляет столбец точек и его пробелы
  • s/ 0.*([NWY]P_[^;]+).*/\1/ - заменить «0», за которым следует ноль или более символов, строка «N», «W» или «Y», за которой следует «P_», за которым следует хотя бы один символ, не являющийся точкой с запятой (сохранение этой строки в group), за которым следует ноль или более символов в сохраненной строке - это берет конец строки, извлекает первую строку WP и удаляет все остальное

Пример выполнения

$ <YP sed -E 's/.*CDS //;s/ *\. //;s/ 0.*([NWY]P_[^;]+).*/\1/'
192004  192117  +  WP_013277182.1
1753871 1754437  +  NP_013278608.1
233759  235705  +  YP_013277222.1
486732  488687  +  WP_013277438.1
1
ответ дан 25.10.2019, 12:33

Использование Perl:

perl -naE 'say "$F[4] $F[5] $F[7] ", /([NWY]P_.*?);/'
  • perl -naE для каждой строки, разбитых на поля и ...
  • say "$F[4] $F[5] $F[7] ", /([NWY]P_.*?);/ ... и распечатать 4, 5, 7 и регулярное выражение
3
ответ дан 25.10.2019, 12:33
  • 1
    Некоторое время назад я удивлялся, почему пятое поле - $F[4], исследуются значения по умолчанию для входного разделителя perl и т. Д., Чтобы окончательно понять, что perl начинает нумерацию полей в 0. :) – hakre 03.05.2019, 13:56
  • 2
    Чтобы иметь возможность более гибко устанавливать разделитель поля вывода, измените переменную $,, например, для двух пробелов (см. OP): perl -naE '$,=" "; say $F[4], $F[5], $F[7], /(WP_.*?);/' – brontea 03.05.2019, 14:04
  • 3
    @ Dessert, спасибо. Это хорошая идея. Пример, представленный OP, имеет переменный разделитель выходного поля, поэтому я не воспринял это всерьез. – B-Tron of the Autobots 03.05.2019, 14:12
  • 4
    Можете ли вы объяснить /(WP_.*?);/, пожалуйста? Почему это не соответствует больше, чем просто до первой точки с запятой, и что означает знак вопроса? – brontea 03.05.2019, 14:18
  • 5
    @dessert, .*? - это не жадная версия .*, означающая совпадение как можно меньше. – GvSharma 03.05.2019, 14:22

Теги

Похожие вопросы