我有一個文件(>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」的行,並重新排列第 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($9, a, ";")
print substr(a[1], 4)
awk 索引從 開始1
。
另一種選擇是修改輸入欄位分隔符號 ( FS
)。
FS
是空格,預設為“”——這也有特殊效果忽略前導空格和尾隨空格。
另外,可以將其設為tab,而不是使用print $1, \t, ...
或變體。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
and 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