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番目のフィールドから「gene」を含む行のみを抽出し、ID値(DDX11L1など)のみを含むように9番目のフィールドを並べ替えたいと思います。希望の出力は次のとおりです。

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

別のオプションは、入力フィールド区切り文字(FS)を変更することです。 FS空白です。デフォルトは「」です。ここにも特殊効果があります。先行および末尾のスペースを無視

print $1, \t, ...また、使用や変形の代わりにタブに設定することもできます。printfOFS


例:

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

また見てくださいグループを開く 変数と特殊変数はい

ゴークマニュアル- これは通常、awkのgawk拡張の場合に表示されます。

答え3

awk以下は、使用の明示的な要求にもかかわらず、公開できるBashソリューションです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

関連情報