筛选以多个数组为条件的文件行

时间:2018-06-20 12:51:34

标签: arrays loops awk conditional

我有多个文件(N> 1000),其中包含qtl摘要数据,例如假设第一个文件由六行组成(实际上,它们都是GWA /估算文件,具有> 10M个SNP)

cat QTL.1.txt 
Chr Rs  BP  beta    se  pvalue
11  rs11224233  134945522   0.150216    0.736939    0.962375  
11  rs4616056   134945709   0.129518    0.371824    0.910326   
11  rs11823417  134945710   0.103462    0.41737 0.845826  
11  rs80294507  134945765   0.150336    0.735363    0.961403  
11  rs61907173  134946034   0.104531    0.158224    0.884548  
11  rs147621717 134946277   0.105365    0.196168    0.86476

我想根据染色体和基因列表的位置过滤每个数据集(我的列表有100个基因,但现在假设它有2个基因);因此创建N_QTL * N_Genes文件。我想了解每个QTL的每个基因/位置。基因的染色体,位置和名称存储在四个阵列中,我想迭代读取这些阵列,并保存每个基因的每个qtl文件的输出。

到目前为止,我所做的没有任何效果,我知道awk并非做到这一点的最佳方法:

    declare -a array1    
    declare -a array2  
    declare -a array3  
    declare -a array4 

    array1=(11 11) #chromosome   
    array2=(134945709 134945765) #start gene position  
    array3=(134946034 134946277) #end gene position  
    array4=(A B) # gene name  


    for qtl in 1; do # in reality it would be for qtl in 1 1000 

         for ((i=0; i<${#array1[@]}; i++)); do  

        cat QTL.$qtl.txt | awk '$1=='array1[$i]' && $3>='array2[$i]' && 
        $3<='array3[$i]' {print$0}' >  Gene.${array4[$i]}_QTL.$qtl.txt; 
        done; 
    done

awk内的$ 1是染色体,$ 3是位置,因此要根据它们进行过滤。

所以我对基因A的QTL.1.txt的预期输出将是

cat Gene.A_QTL.1.txt
Chr Rs  BP  beta    se  pvalue  
11  rs4616056   134945709   0.129518    0.371824    0.910326   
11  rs11823417  134945710   0.103462    0.41737 0.845826  
11  rs80294507  134945765   0.150336    0.735363    0.961403  
11  rs61907173  134946034   0.104531    0.158224    0.884548  

对于基因B,对于QTL.1.txt,

cat Gene.B_QTL.1.txt
Chr Rs  BP  beta    se  pvalue
11  rs80294507  134945765   0.150336    0.735363    0.961403  
11  rs61907173  134946034   0.104531    0.158224    0.884548  
11  rs147621717 134946277   0.105365    0.196168    0.86476

我最终得到的是空文件,这可能是因为我要求根据数组的值过滤这些列的方式不起作用。

非常感谢您的帮助! 预先谢谢你

2 个答案:

答案 0 :(得分:1)

混合bash和awk来解析文件并不总是最好的方法。

这里只有awk的解决方案。

假设您已将信息分配给文件中的bash数组:

$ cat info
11 134945765 154945765 Gene1
12 134945522 174945522 Gene2

您可以使用以下awk脚本对数据文件执行查找:

awk 'NR==FNR{
       for(i=2;i<=NF;i++) 
         a[$1,i]=$i
         next
     } 
     a[$1,2]<=$3 && a[$1,3]>=$3{
        print $0 > a[$1,4]"_QTL"
     }' info QTL.1.txt

这将创建一个具有以下内容的文件:

$ cat Gene1_QTL
11 rs80294507 134945765 0.150336 0.735363 0.961403
11 rs61907173 134946034 0.104531 0.158224 0.884548
11 rs147621717 134946277 0.105365 0.196168 0.86476

也许不是您正在查看的内容,但是我希望这会有所帮助...

答案 1 :(得分:0)

如果多个基因位于同一条染色体上(使用基因名称而不是chr作为密钥),则可能要执行以下操作:

awk 'NR==FNR{
        chr[$4]=$1;
        start[$4]=$2;
        end[$4]=$3;
     } 
     NR!=FNR{
        for (var in chr){
            name=var"_"FILENAME;
            if(chr[var]==$1 && start[var] <=$3 && end[var]>=$3){
                print $0 > name;
            }
        }
    }'  info QTL