[英]Extract last part of the string when separator is not always the same using awk
我有看起来像这样的行的文件。 文件在这里
ID=4;Dbxref=766;Name=LOC2;gene_biotype=protein_coding
ID=5;Dbxref=800;Name=LOC3;gene_biotype=lncRNA
ID=6;Dbxref=900;Name=LOC4;gene_biotype=protein_coding;partial=true;start_range=.,338076
ID=7;Dbxref=905;Name=LOC5;gene_biotype=pseudogene;pseudo=true
我试图抓住字符串的最后一部分......但结尾并不总是一致的
我试过了:
while read -r line ; do
ID=`echo $line | awk -F"ID=" '{print $2}' | awk -F";" '{print $1}'`
Biotype=`echo $line | awk -F"gene_biotype=" '{print $2}'`
echo -e $ID"\t"$Biotype >> file.txt
done << (grep $'\tgene\t' originalfile.txt)
生物型是不起作用的部分。 理想情况下,输出看起来像
4 protein_coding
5 lncRNA
6 protein_coding;partial=true;start_range=.,338076
7 pseudogene;pseudo=true
我也试过:
Biotype=`echo $line | awk -F"gene_biotype=" '{print $NF}'`
但它最终什么也没有节省。 任何建议表示赞赏...
使用理解-E
的 sed 来使用 ERE(例如 GNU sed 或 OSX/BSD sed):
$ sed -E 's/[^=]*=([^;]*)(;[^;]*){2}[^=]*=/\1\t/' file
4 protein_coding
5 lncRNA
6 protein_coding;partial=true;start_range=.,338076
7 pseudogene;pseudo=true
使用任何 POSIX sed:
$ sed 's/[^=]*=\([^;]*\)\(;[^;]*\)\{2\}[^=]*=/\1\t/' file
4 protein_coding
5 lncRNA
6 protein_coding;partial=true;start_range=.,338076
7 pseudogene;pseudo=true
此外,这里有一种通常使用您将来拥有的 tag=value 数据类型的方法,即首先创建一个数组(下面的f[]
)将每个标签/名称映射到它的关联值,然后您就可以访问值按名称进行比较、打印等:
$ cat tst.awk
BEGIN { FS=";"; OFS="\t" }
{
delete f
for (i=1; i<=NF; i++) {
tag = val = $i
sub(/=.*/,"",tag)
sub(/[^=]+=/,"",val)
f[tag] = val
}
<< do something with "f[tag]"s >>
}
您可以通过以下方式解决您当前的问题:
$ cat tst.awk
BEGIN { FS=";"; OFS="\t" }
{
delete f
for (i=1; i<=NF; i++) {
tag = val = $i
sub(/=.*/,"",tag)
sub(/[^=]+=/,"",val)
f[tag] = val
}
sub(/.*;gene_biotype=/,"")
print f["ID"], $0
}
$ awk -f tst.awk file
4 protein_coding
5 lncRNA
6 protein_coding;partial=true;start_range=.,338076
7 pseudogene;pseudo=true
但是您还可以根据不同值的复合条件包含打印行,以与输入不同的顺序打印列,等等。例如:
$ cat tst.awk
BEGIN { FS=";"; OFS="\t" }
{
delete f
for (i=1; i<=NF; i++) {
tag = val = $i
sub(/=.*/,"",tag)
sub(/[^=]+=/,"",val)
f[tag] = val
}
}
( (f["Dbxref"] > 800) && (f["partial"] == "true") ) || (f["gene_biotype"] == "protein_coding") {
print f["Name"], f["ID"]
}
.
$ awk -f tst.awk file
LOC2 4
LOC4 6
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.