次のようなファイル (>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
。
もう一つの選択肢は、入力フィールドの区切り文字( )を変更することですFS
。
FS
デフォルトではスペース「 」ですが、これには次のような特殊効果もあります。先頭と末尾のスペースを無視する。
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
) はタブとして、FS
awk 内では代替として使用されます。また、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