我正在尝试在制表符分隔的两个大文件之间进行比较。我一直在尝试使用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中打印列中的相应值?#这似乎是最接近的,但没有在我想要的第三个文件中全部打印出来,仍然无法完全弄清语法
尝试:
$ 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 s
。b
使用制表符作为分隔符,将该字符串拆分为数组。
该函数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] 删除。
我来说两句