Awk比较3个值,第一个文件值之间的第二个文件值,两个文件之间的多列打印输出到第三个文件

生态

我正在尝试在制表符分隔的两个大文件之间进行比较。我一直在尝试使用awk&bash(Ubuntu 15.10),python(v3.5)和powershell(Windows 10)。我唯一的背景是Java,但是我的领域倾向于坚持使用脚本语言。

我想看看

档案1 A []

1   gramene gene    4854    9652    .   -   .   ID=gene:GRMZM2G059865;biotype=protein_coding;description=Uncharacterized protein  [Source:UniProtKB/TrEMBL%3BAcc:C0P8I2];gene_id=GRMZM2G059865;logic_name=genebuilder;version=1
1   gramene gene    9882    10387   .   -   .   ID=gene:GRMZM5G888250;biotype=protein_coding;gene_id=GRMZM5G888250;logic_name=genebuilder;version=1
1   gramene gene    109519  111769  .   -   .   ID=gene:GRMZM2G093344;biotype=protein_coding;gene_id=GRMZM2G093344;logic_name=genebuilder;version=1
1   gramene gene    136307  138929  .   +   .   ID=gene:GRMZM2G093399;biotype=protein_coding;gene_id=GRMZM2G093399;logic_name=genebuilder;version=1

档案2 B []

S1_6370 T/C 1   6370    +
S1_8210 T   1   8210    +
S1_8376 A   1   8376    +
S1_9889 A   1   9889    +

输出

1   ID=gene:GRMZM2G059865   4857    9652    -   S1_6370 T/C 6370    +   
1   ID=gene:GRMZM2G059865   4857    9652    -   S1_8210 T   8210    +
1   ID=gene:GRMZM2G059865   4857    9652    -   S1_8376 A   8376    +
1   ID=gene:GRMZM5G888250   9882    10387   -   S1_9889 A   9889    +

我的一般逻辑

loop (until end of A[ ] and B[ ])
if
B[$4]>A[$4] && B[$4]<A[$5]  #if the value in B column 4 is in between the values in A columns 4 & 5.
then
-F”\t” print {A[1], A[9(filtered)], A[$4FS$5], B[$1], B[$2], B[$3], B[$4], B[$5]}   #hopefully reflects awk column calls if the two files were able to have their columns defined that way.
movea++ # to see if the next set of B column 4 values is in between the values in A columns 4 & 5 
else
moveb++ #to see if the next set of A columns 4&5 values contain the current vales of B column 4 in them.

我知道这种逻辑不会遵循我所知道的任何语言,但是在某些方面是相似的。似乎NR和FNR是awk中的两个内置运行值。Awk帮助我很轻松地将B [$ 1]中具有10个值的File 2分割成10个文件,并且cut减少了您在此处看到的5列中的几百列(〜255 +)。现在,我正在处理文件2大小大约为2 MB,而不是1.6 GB的文件。除了减少加载时间,我还想简化循环。自从我缩小文件大小以来,我还没有回溯到以前的python或powershell尝试。我说服自己,他们只是不会使用内置的库或cmdlet来读取我的文件。如果无法找到awk解决方案,我会尽快尝试。

使用awk比较多个文件和列#引用的Awk大于小于但在设定范围内#引用的有效按列值将一个文件拆分为多个文件有效的一件事使用awk在行#中获取特定字符串能够过滤列9如何检查列值位于其他文件中两列的值之间,并在Unix中打印列中的相应值?#这似乎是最接近的,但没有在我想要的第三个文件中全部打印出来,仍然无法完全弄清语法

约翰1024

尝试:

$ awk 'BEGIN{x=getline s <"B"; split(s,b,"\t")} !x{exit} {sub(/;.*/,"",$9); while (x && $4<b[4] && b[4]<$5){print $1,$9,$4,$5,$7,b[1],b[2],b[4],b[5]; x=getline s <"B"; split(s,b,"\t")}}' OFS='\t' A
1       ID=gene:GRMZM2G059865   4854    9652    -       S1_6370 T/C     6370    +
1       ID=gene:GRMZM2G059865   4854    9652    -       S1_8210 T       8210    +
1       ID=gene:GRMZM2G059865   4854    9652    -       S1_8376 A       8376    +
1       ID=gene:GRMZM5G888250   9882    10387   -       S1_9889 A       9889    +

怎么运行的

该程序隐式循环文件A的各行。

  • BEGIN{x=getline s <"B"; split(s,b,"\t")}

    在开始读取文件A之前,将文件B的第一行读入string sb使用制表符作为分隔符,将该字符串拆分为数组

    该函数getline将设置x为true,直到用完所有行以读取文件B。

  • !x{exit}

    如果我们用完了要读入文件B的行,则exit该程序。

  • sub(/;.*/,"",$9)

    删除;文件A的字段9之后的所有内容

  • while (x && $4<b[4] && b[4]<$5){print $1,$9,$4,$5,$7,b[1],b[2],b[4],b[5]; x=getline s <"B"; split(s,b,"\t")}

    循环浏览文件B的各行,只要行B的第四个字段在文件A的字段4和5的值之间,就打印请求的输出。

    该函数getline将设置x为true,直到用完所有行以读取文件B。

  • OFS='\t'

    将输出字段分隔符设置为选项卡。

多行版本

对于那些喜欢将awk代码分成多行的用户:

awk '

BEGIN{
    x=getline s <"B"
    split(s,b,"\t")
} 

!x {
    exit
} 

{   
    sub(/;.*/,"",$9)
    while (x && $4<b[4] && b[4]<$5) {
        print $1,$9,$4,$5,$7,b[1],b[2],b[4],b[5]
        x=getline s <"B"; split(s,b,"\t")
    }
}
' OFS='\t' A

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档