我有一个VCF文件(制表符分隔),其中第二列中缺少某些“RPB”值,它将整行向左移动。
我有以下内容:
1 AF1=23 AC1=23
2 RPB=123 AF1=23 AC1=23
3 AF1=23 AC1=23
我需要以下内容:
1 NULL AF1=23 AC1=23
2 RPB=123 AF1=23 AC1=23
3 NULL AF1=23 AC1=23
我试过了,它工作很悲惨......:
awk 'if($2="AF1%" {print $1,"\t"NULL"\t", print$2, print$3}' input.vcf > output.vcf
我必须将此VCF导入MySQL,因此必须保留制表符分隔。任何想法?
答案 0 :(得分:2)
$ awk 'NF<4{sub(/\t/,"&NULL&")}1' file
1 NULL AF1=23 AC1=23
2 RPB=123 AF1=23 AC1=23
3 NULL AF1=23 AC1=23
顺便说一句,你尝试的功能解决方案并不太远:
awk 'if($2="AF1%" {print $1,"\t"NULL"\t", print$2, print$3}' input.vcf
这个最小化版本可以产生你想要的输出:
awk '{if($2~/^AF1/) print $1 "\tNULL\t" $2 "\t" $3; else print}' input.vcf
但是你可以看到这不是一种非常惯用的方法。
答案 1 :(得分:1)
kent$ awk -F'\t' -v OFS='\t' '!($2~/^RPB=/){$2="NULL\t"$2}7' file
1 NULL AF1=23 AC1=23
2 RPB=123 AF1=23 AC1=23
3 NULL AF1=23 AC1=23
答案 2 :(得分:0)
恕我直言,你不应该使用正则表达式,试试这个:
#!/bin/bash
cat input.vcf |\
perl -ane '
BEGIN{$c=0;$max_fields=0}
$c2=0;
foreach(@F){
$a[$c][$c2]=$_;
if( $c2 > $max_fields ) {
$max_fields=$c2;
}
$c2++
}
$c++;
END{
foreach $i (@a){
while (@$i < $max_fields + 1 ){
unshift (@$i,"NULL");
}
}
foreach $i (@a){
foreach $x (@$i){
print $x,"\t";
}
print "\n";
}
}'
输出:
bash test.sh
NULL AF1=23 AC1=23
RPB=123 AF1=23 AC1=23
NULL AF1=23 AC1=23
说明:
答案 3 :(得分:0)
基于制表符分隔的输入文件:
awk -v OFS="\t" 'NF==3{$1=$1 OFS "NULL"} 1' input.vcf
如果输入文件没有以制表符分隔,则可以将其更改为以下内容:
awk -v OFS="\t" '{$1=$1 (NF==3 ? OFS "NULL" : "")} 1' input.vcf
在其中任何一个中,当NF==3
重新分配第一个字段以包含缺失的数据时。在第一个示例中,只有更改行的输出分隔符需要调整,但是当数据不是制表符分隔时,每行需要在1
之前重新分配“重新计算”,这是{{1}}打印整条线。
当输入文件以制表符分隔时,Ed的答案之处在于,当替换发生时,整行输出分隔符不会被“重新计算”,因为它是第一个被替换的分隔符。