Удалите строку из определенного поля с помощью awk / sed

У меня есть файл (> 80 000 строк), который выглядит вот так:

chr1 GTF2GFF chromosome 1 249213345 . . . ID=chr1;Name=chr1 chr1 GTF2GFF gene 11874 14408 . + . ID=DDX11L1;Note=unknown;Name=DDX11L1 chr1 GTF2GFF exon 11874 12227 . + . Parent=NR_046018_1 chr1 GTF2GFF exon 12613 12721 . + . Parent=NR_046018_1 chr1 GTF2GFF exon 13221 14408 . + . Parent=NR_046018_1 chr1 GTF2GFF gene 14362 29370 . - . ID=WASH7P;Note=unknown;Name=WASH7P chr1 GTF2GFF exon 14362 14829 . - . Parent=NR_024540 chr1 GTF2GFF exon 14970 15038 . - . Parent=NR_024540 chr1 GTF2GFF exon 15796 15947 . - . Parent=NR_024540 chr1 GTF2GFF exon 16607 16765 . - . Parent=NR_024540 chr1 GTF2GFF exon 16858 17055 . - . Parent=NR_024540 chr1 GTF2GFF exon 17233 17368 . - . Parent=NR_024540 chr1 GTF2GFF exon 17606 17742 . - . Parent=NR_024540 chr1 GTF2GFF exon 17915 18061 . - . Parent=NR_024540 chr1 GTF2GFF exon 18268 18366 . - . Parent=NR_024540 chr1 GTF2GFF exon 24738 24891 . - . Parent=NR_024540 chr1 GTF2GFF exon 29321 29370 . - . Parent=NR_024540 chr1 GTF2GFF gene 34611 36081 . - . ID=FAM138A;Note=unknown;Name=FAM138A chr1 GTF2GFF exon 34611 35174 . - . Parent=NR_026818 chr1 GTF2GFF exon 35277 35481 . - . Parent=NR_026818 

и я хочу извлечь только строки, содержащие «ген» в третьем поле, и переустановить 9-ое поле, чтобы содержать только значение ID (например, DDX11L1). Это желаемый результат:

 chr1 11874 14408 DDX11L1 . + chr1 14362 29370 WASH7P . - chr1 34611 36081 FAM138A . - 

Используя awk, я легко получил нужные поля:

 head -20 genes.gff3 | awk '$3=="gene" {print $1 "\t" $4 "\t" $5 "\t" $9"\t" $6 "\t" $7}' chr1 11874 14408 ID=DDX11L1;Note=unknown;Name=DDX11L1 . + chr1 14362 29370 ID=WASH7P;Note=unknown;Name=WASH7P . - chr1 34611 36081 ID=FAM138A;Note=unknown;Name=FAM138A . - 

Но я борюсь с получением значения ID. Я попытался подключить его к sed:

 head -20 genes.gff3 | awk '$3=="gene" {print $1 "\t" $4 "\t" $5 "\t" $9"\t" $6 "\t" $7}' | sed 's/\(^.+\t\)ID=\(\w+\).+\(\t.+$\)/\1\2\3/g' 

а также gsub

 head -20 genes.gff3 | awk '$3=="gene" {gsub(/\(^.+\t\)ID=\(\w+\).+\(\t.+$\)/, "\1\2\3", $9); print $1 "\t" $4 "\t" $5 "\t" $9"\t" $6 "\t" $7}' 

Но результат такой же, как при использовании awk. Как я могу извлечь значение ID? Я чувствую, что я действительно близок к решению здесь.

Приветствия.

  • Добавить что-то в каждый список в файле
  • Как добавить заголовок и / или нижний колонтитул в поток sed или awk?
  • Исключение одиночных кавычек ** с ** псевдонимом
  • sed снятие комментариев в строке
  • как grep текст до следующего пространства?
  • Linux sed - поиск подстановочной строки без пробелов в ней
  • Как объединить все CSV S в один CSV в порядке
  • исключая символ перед определенным символом в sed
  • 4 Solutions collect form web for “Удалите строку из определенного поля с помощью awk / sed”

    Вы можете split поле и использовать substr :

     split($9, a, ";") print substr(a[1], 4) 

    Индексы Awk начинаются с 1 .

    Другим вариантом может быть изменение разделителя полей ввода ( FS ). FS – это пространство, «», по умолчанию, что также имеет особый эффект игнорирования начальных и конечных пробелов .

    Кроме того, вместо использования print $1, \t, ... или варианта printf можно установить OFS в tab.


    Примеры:

    Изменение FS:

     awk -F" +|;|=" ' $3 == "gene" { printf("%s\t%s\t%s\t%s\t%s\t%s\t\n", $1, $4, $5, $10, $6, $7); } ' data.file 

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

     awk ' $3 == "gene" { split($9, a, ";") printf("%s\t%s\t%s\t%s\t%s\t%s\t\n", $1, $4, $5, substr(a[1], 3), $6, $7); } ' data.file 

    OFS и FS:

    Выходной полевой разделитель ( OFS ) в качестве вкладки и альтернативный FS внутри awk. Также обновлен FS чтобы включить вкладку:

     awk ' BEGIN { FS="[ \t]+|;|=" OFS="\t" } $3 == "gene" { print $1, $4, $5, $10, $6, $7 } ' data.file 

    Также см. « Переменные группы» и «Специальные переменные» , Примеры .

    Gawk manual – обычно это замечается, когда вещи являются расширением gawk для awk.

    Разделитель поля функции split является регулярным выражением, поэтому вы можете разделить on = OR ; , Если вы знаете, что $9 начинается с «ID =», то

     awk -v OFS='\t' ' $3 == "gene" { split($9, id, /[=;]/) print $1, $4, $5, id[2], $6, $7 } ' genes.gff3 

    Если «ID =» не обязательно находится в начале поля, то есть еще немного работы:

     awk -v OFS='\t' ' $3 == "gene" { id = "" len = split($9, f, /[=;]/) for (i=1; i<len; i++) { if (f[i] == "ID") { id = f[i+1] break } } print $1, $4, $5, id, $6, $7 } ' genes.gff3 

    Это решение Bash, которое позволяло мне публиковать, несмотря на явный запрос с просьбой использовать awk и sed :

     show_genes() { local filename="$1" while read -ra larr; do if [[ ${larr[2]} = gene ]]; then larr[8]="${larr[8]%%;*}" larr[8]="${larr[8]#ID=}" printf '%s\n' "${larr[*]}" fi done < "$filename" } 

    Использование: show_genes /path/to/some/file.txt

    Пример вывода:

     [rany$] cat data.txt romosome 1 249213345 . . . ID=chr1;Name=chr1 chr1 GTF2GFF gene 11874 14408 . + . ID=DDX11L1;Note=unknown;Name=DDX11L1 chr1 GTF2GFF exon 11874 12227 . + . Parent=NR_046018_1 chr1 GTF2GFF exon 12613 12721 . + . Parent=NR_046018_1 chr1 GTF2GFF exon 13221 14408 . + . Parent=NR_046018_1 chr1 GTF2GFF gene 14362 29370 . - . ID=WASH7P;Note=unknown;Name=WASH7P chr1 GTF2GFF exon 14362 14829 . - . Parent=NR_024540 chr1 GTF2GFF exon 14970 15038 . - . Parent=NR_024540 chr1 GTF2GFF exon 15796 15947 . - . Parent=NR_024540 chr1 GTF2GFF exon 16607 16765 . - . Parent=NR_024540 chr1 GTF2GFF exon 16858 17055 . - . Parent=NR_024540 chr1 GTF2GFF exon 17233 17368 . - . Parent=NR_024540 chr1 GTF2GFF exon 17606 17742 . - . Parent=NR_024540 chr1 GTF2GFF exon 17915 18061 . - . Parent=NR_024540 chr1 GTF2GFF exon 18268 18366 . - . Parent=NR_024540 chr1 GTF2GFF exon 24738 24891 . - . Parent=NR_024540 chr1 GTF2GFF exon 29321 29370 . - . Parent=NR_024540 chr1 GTF2GFF gene 34611 36081 . - . ID=FAM138A;Note=unknown;Name=FAM138A chr1 GTF2GFF exon 34611 35174 . - . Parent=NR_026818 chr1 GTF2GFF exon 35277 35481 . - . Parent=NR_026818 [rany$] show_genes data.txt chr1 GTF2GFF gene 11874 14408 . + . DDX11L1 chr1 GTF2GFF gene 14362 29370 . - . WASH7P chr1 GTF2GFF gene 34611 36081 . - . FAM138A [rany$] 

    Просто быстрый ответ на кофе-брейк

     perl -ne 's/\t.*?\tgene// #remove \t F2 \t gene and s/\S*\tID=(.*?);.*/$1/ #remove \t Fn \t ID=.... keeping the id and print' file 
    Interesting Posts

    Чтение / обработка данных столбца для n-го повторения

    блокировка клавиатуры после удержания клавиши ctrl

    Как включить протокол NFS4

    как перемещать набор файлов в один слой

    Использование переменной внутри последовательности команд в bash для дополнения существующей строки – синтаксическая ошибка или ошибочный дизайн?

    Как установить PostgreSQL и PostGIS на Ubuntu 14.04 и разрешить удаленный доступ через Интернет?

    вывод вершины усекает до 80 столбцов при запуске cron

    Альтернатива Webmin, которая устанавливает и запускает клиентскую машину и обменивается данными через SSH

    Когда вы ожидаете на странице, какой сон является задачей?

    Пульсаудио по сети – мгновенно меняет мощность

    ACPI пробуждение с клавиатуры / мыши через / proc / acpi / wakeup после приостановки. Как найти правильное устройство?

    Определите доли SMB, которые я прочитал и / или напишу

    USB-мышь не работает

    ksh, выполнить действие при достижении максимального значения цикла

    Разверните раздел в Gparted назад или перемещение назад + expand

    Linux и Unix - лучшая ОС в мире.