私は大きなものを持っていますgtf
。ここでeg.gtf
次のように共有します。
chr22 Cufflinks transcript 10695955 10696708 . + . transcript_id "first_11345700"; gene_id "XLOC_158970"; gene_name "XLOC_158970"; oId "TCONS_00353198"; class_code "u"; tss_id "TSS369767"; original_gene_id "XLOC_158970";
chr22 Cufflinks exon 10702915 10703826 . + . transcript_id "first_11345701"; gene_id "ENSG00000277248.1"; gene_name "ENSG00000277248.1"; exon_number "1"; original_gene_id "ENSG00000277248.1";
chr22 Cufflinks transcript 10702915 10707278 . + . transcript_id "first_11345701"; gene_id "ENSG00000277248.1"; gene_name "ENSG00000277248.1"; oId "TCONS_00353199"; class_code "u"; tss_id "TSS369769"; original_gene_id "ENSG00000277248.1";
awk
次の列番号を使用して必須フィールドを抽出しました。
cat eg.gtf | awk 'OFS="\t" {if ($3=="transcript") {print $1,$4-1,$5,$12,$7}}' | tr -d '";'
出力は次のとおりです。
chr22 10695954 10696708 XLOC_158970 +
chr22 10702914 10707278 ENSG00000277248.1 +
12
コマンドに列番号を使用したくありませんが、awk
名前のあるフィールドを抽出したいと思います。
メモ: 12th column has different names, starting with E or X or M or N or S
。
12
コマンドに列番号を指定せずに12番目のフィールドをどのように取得できますかawk
?gene_id
列11の用語を使用してフィールド12を取得する方法はありますか?
答え1
すべてのUnixシステムのすべてのシェルでawkを使用してください。
$ cat tst.awk
BEGIN {
FS=OFS="\t"
}
$3 == "transcript" {
n = split($NF,tmp,/[; "]+/)
for ( i=1; i<n; i+=2 ) {
vals[tmp[i]] = tmp[i+1]
}
print $1, $4-1, $5, vals["gene_id"], $7
}
$ awk -f tst.awk file
chr22 10695954 10696708 XLOC_158970 +
chr22 10702914 10707278 ENSG00000277248.1 +
答え2
GTFはタブ区切り形式なので、サブフィールドの順序を信頼できません。代わりにテキスト解析を使用する必要があります。私はPerlを使って次のことをします。
$ perl -F'\t' -lane '
if($F[2] eq "transcript"){
$gene_id = /gene_id\s*"([^"]+)"/ ? $1 : "None";
print join("\t",$F[0],$F[3]-1,$F[4],$gene_id,$F[6])
}' file
chr22 10695954 10696708 XLOC_158970 +
chr22 10702914 10707278 ENSG00000277248.1 +
これは、遺伝子名がない場合は「なし」で印刷するという利点があります(例えば、コード化されていない転写物には遺伝子名がないか、不明な転写物などがある可能性があります)。
答え3
使用ミラー()また、入力がタブで区切られたファイルで、9番目のフィールドが -- 区切りのキーと値のフィールドで構成されていると仮定しますmlr
(キーは二重引用符で囲まれた値文字列でスペースで区切られます)。;
mlr --inidx --ifs tab --otsv --headerless-csv-output \
filter '$3 == "transcript"' then \
put '$4 -= 1; $9 = gsub($9, "; ", ";"); $9 = gsub($9, "\"", "")' then \
nest --explode --pairs --across-fields --nested-fs ';' --nested-ps ' ' -f 9 then \
cut -o -f 1,4,5,gene_id,7 file.gtf
これにより、ファイルは整数インデックスタブ区切りフィールドとして読み取られ、ヘッダーなしタブ区切りデータ出力(TSV)が生成されます。 Millerは挿入された引用符について文句を言うため、データをTSVに読み取ることはできません(フィールド自体が引用符でない場合、フィールドに引用符を挿入できません)。
filter
3番目のフィールドが文字列以外のすべてのレコードを削除すると、処理が開始されますtranscript
。
次に、put
を使用して4番目のフィールドの値を1ずつ減らします。また、;
9番目のフィールド(追加の説明があるフィールド)の各フィールドの後のスペースとすべてのフィールドの二重引用符を削除しました。
このnest --explode
仕事は新しい名前付きキーと値のペアを「爆発」して、フィールド9のデータからフィールドを抽出します。
cut
その後、そのフィールドを含む目的のフィールドを抽出するために使用できますgene_id
。
質問のデータを出力します。
chr22 10695954 10696708 XLOC_158970 +
chr22 10702914 10707278 ENSG00000277248.1 +