私は大きなものを持っていますGTFファイル、次のように:
# ./stringtie -p 4 -G /home/humangenome_hg19/homo_gtf_file.gtf -o strAD1_as/transcripts.gtf -l strAD1 /home/software/star-2.5.2b/bin/Linux_x86_64/mapA1Aligned.sortedByCoord.out.bam
# StringTie version 1.3.2d
1 StringTie transcript 30267 31109 1000 + . gene_id "strAD1.1"; transcript_id "strAD1.1.1"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.028725"; FPKM "0.053510"; TPM "0.109957";
1 StringTie exon 30267 30667 1000 + . gene_id "strAD1.1"; transcript_id "strAD1.1.1"; exon_number "1"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.014218";
1 StringTie exon 30976 31109 1000 + . gene_id "strAD1.1"; transcript_id "strAD1.1.1"; exon_number "2"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.072139";
gene_id
9列には、およびtranscript_id
のみreference_id
含めたいと思いますref_gene_id
。列9にあり、スペースで区切られています(列自体はタブで区切られています)。簡単なコマンドを使用してLinuxでこれらの列を作成する方法を教えてください。私はExcelを使用したくありません。
答え1
理想的には、データはGTF形式であるため、GTFパーサーを使用して解析する必要があります。現在、このようなパーサーや解析ライブラリはインストールされていないため、私のソリューションはあなたが質問に提供したデータのみに基づいています。
列 9 を抽出するには、次のようにします。
$ cut -f 9 data.gtf
gene_id "strAD1.1"; transcript_id "strAD1.1.1"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.028725"; FPKM "0.053510"; TPM "0.109957";
gene_id "strAD1.1"; transcript_id "strAD1.1.1"; exon_number "1"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.014218";
gene_id "strAD1.1"; transcript_id "strAD1.1.1"; exon_number "2"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.072139";
ここで目的のデータを取得するには、転写物とエクソンの属性がデータ内で異なる順序になっているため、別々に処理する必要があります。これを行いawk
、現在の行に文字列が含まれているかどうかによって入力データとは異なるフィールドを出力しますexon_number
。
$ cut -f 9 data.gtf | awk '/exon_number/ { print $2, $4, $8, $10; next } { print $2, $4, $6, $8 }'
"strAD1.1"; "strAD1.1.1"; "ENST00000469289"; "ENSG00000243485";
"strAD1.1"; "strAD1.1.1"; "ENST00000469289"; "ENSG00000243485";
"strAD1.1"; "strAD1.1.1"; "ENST00000469289"; "ENSG00000243485";
次に二重引用符とセミコロンを削除します。
$ cut -f 9 data.gtf | awk '/exon_number/ { print $2, $4, $8, $10; next } { print $2, $4, $6, $8 }' | tr -d '";'
strAD1.1 strAD1.1.1 ENST00000469289 ENSG00000243485
strAD1.1 strAD1.1.1 ENST00000469289 ENSG00000243485
strAD1.1 strAD1.1.1 ENST00000469289 ENSG00000243485
答え2
たぶんただ:
< file cut -sd '"' -f2,4,8,10 | tr '"' ' '
つまり、入力を別々の"
列のリストとして処理し、列2、4、8、および10を抽出します。
GNUを使用するcut
と。| tr '"' ' '
--output-delimiter=' '
これは"
、文字が行の他の場所には表示されず、対応する、gene_id
...transcript_id
属性が常にその順序で表示され、常に表示されると仮定します。
Kusalanandaが指摘したように、あなたの例ではそうではありません。2,4,6,8
最初の行と2,4,8,10
他の行は次のようにする必要があります。
より表現力のある一致を作成するには、タブで区切られた9番目の列のみを考慮して正しい属性名を見つける必要があります。正規表現を使用できます。たとえば、次のようになります。
< file pcregrep -o1 -o2 -o3 -o4 --om-separator=' ' '(?x)
^(?:[^\t]*+\t){8}(?=[^\t]*? \b gene_id \ +"([^"\t]*)")
(?=[^\t]*? \b transcript_id \ +"([^"\t]*)")
(?=[^\t]*? \b reference_id \ +"([^"\t]*)")
(?=[^\t]*? \b ref_gene_id \ +"([^"\t]*)")'
そのバージョンがないpcregrep
場合、またはバージョンが古すぎてサポートできない場合は、-o1...
次のものを使用できますperl
。
< file perl -lne 'print "$1 $2 $3 $4" if m{
^(?:[^\t]*+\t){8}(?=[^\t]*? \b gene_id \ +"([^"\t]*)")
(?=[^\t]*? \b transcript_id \ +"([^"\t]*)")
(?=[^\t]*? \b reference_id \ +"([^"\t]*)")
(?=[^\t]*? \b ref_gene_id \ +"([^"\t]*)")}x'
この正規表現は最初に最初の8つのフィールド((?:[^\t]*+\t){8}
)と一致し、次に4つの予測式()があるため、次の内容が(?=...)
4つの予測式とすべて一致する場合は、8つのフィールドを一致させます。各予測式は属性の1つを見つけて値をキャプチャします(ウィジェットで(...)
)。このようにキャプチャされた値は、、、、$1
で$2
使用$3
できます$4
。
これにより、属性を任意の順序で並べ替えることができます。
次の方法でだますことができます。
1 2 3 4 5 6 7 8 gene_id "transcript_id " ...
この問題は解決できますが、入力に表示されるとは思わないので、努力する価値はありません。
を使用すると、9番目のフィールドのperl
より正式な解析を実行することもできます。それは次のとおりです。
< file perl -F'\t' -lane '
my %field;
while ($F[8] =~ /(\w+) +"(.*?)"/g) {$field{$1}=$2}
if (%field) {
print join " ", @field{
qw(gene_id transcript_id reference_id ref_gene_id
)}
}'
(ここでは、1つ以上の属性が見つかるたびに1行が印刷されます(他のメソッドによって要求されたすべての属性とは反対)。