awk/sed を使用して特定のフィールドから文字列を削除する

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

そして、3 番目のフィールドに「遺伝子」が含まれる行のみを抽出し、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 値を抽出するにはどうすればよいでしょうか? ここで解決にかなり近づいたように感じます。

乾杯。

答え1

関数のフィールドセパレータはsplit正規表現なので、=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

答え2

あなたは出来るsplitフィールドと使用substrによる:

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

Awk インデックスは から始まります1

もう一つの選択肢は、入力フィールドの区切り文字( )を変更することですFSFSデフォルトではスペース「 」ですが、これには次のような特殊効果もあります。先頭と末尾のスペースを無視する

print $1, \t, ...また、または のバリエーションを使用する代わりに、tab にprintf設定することもできます。OFS


例:

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

分割の使用:

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) はタブとして、FSawk 内では代替として使用されます。また、FSタブを含むように更新されました:

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

' data.file

こちらもご覧くださいオープングループ 変数と特殊変数

Gawk マニュアル– これは通常、awk の gawk 拡張であるときに示されます。

答え3

これは 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$]

答え4

ちょっとしたコーヒーブレイクの答え

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

関連情報