awk添加一列是第3列等于字符串

时间:2014-06-21 22:58:02

标签: awk sed vcf

我有一个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,因此必须保留制表符分隔。任何想法?

4 个答案:

答案 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)

这个awk one-liner会帮助你:

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  

说明:

  1. 上面的代码创建了一个2D数组(行/字段)
  2. 它还存储max_fields
  3. 对于每一行,如果字段数小于max_fields而不是insert&#34; NULL&#34; 一行的开头

答案 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的答案之处在于,当替换发生时,整行输出分隔符不会被“重新计算”,因为它是第一个被替换的分隔符。