我需要从中提取信息的文件如下
2 41620 . T G 100 PASS AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
我需要的输出是
2 41620 CSQ=G missense_variant
主要字段总是被 ||| 除以,但 2 41620 不一定来自第一个字段,CSQ=G 和错义变体不一定来自下一个字段。它不一定是 missense_variant 或类似的,但它始终是第一个 ||| 之后的第一个和第四个字段。
如何在 perl、awk、sed 等中实现?
答案1
由于您提到数据始终位于相同的列中,因此 AWK 适合此任务。然而,小问题是,您的数据在某个点之前以空格作为分隔符,但随后切换到使用竖线作为分隔符。因此,我们需要一些更复杂的 AWK 技巧。
awk '{gsub(/[;]/," ");printf "%s %s ",$1,$2; for(i=1;i<=NF;i++){ if($i~/\|\|\|/) {gsub(/\|/," ");printf "%s %s",$(i+1),$(i+5);break} } printf "\n"; }' testData.txt
将上述代码转换为脚本形式,
#!/usr/bin/awk -f
{
gsub(/[;]/," ");
printf "%s %s ",$1,$2;
for(i=1;i<=NF;i++){
if($i~/\|\|\|/) {
gsub(/\|/," ");
printf "%s %s",$(i+1),$(i+5);
break
}
}
printf "\n";
}
将其放入文件中,调用它myScript.awk
或执行其他操作,添加执行权限chmod +x myScript.awk
并将输入文件作为参数提供给它
示例运行:
$ chmod +x dataExtract.awk
$ ./dataExtract.awk testData.txt
2 41620CSQ=G missense_variant
附注:在问题中你说的missense_variant
是第 4 个字段,但实际上在你发布的例子中那是第 5 个字段。我已进行了相应调整
根据评论的要求进行编辑:
#!/usr/bin/awk -f
{
gsub(/[;]/," ");
printf "%s\t%s\t",$1,$2;
for(i=1;i<=NF;i++){
if($i~/\|\|\|/) {
gsub(/\|/," ");
printf "%s\n" $(i+5);
break
}
}
}