从大型文本文件中提取行的子集

从大型文本文件中提取行的子集

我有一个包含 9 列的大文件,以制表符分隔。该文件约39MB,约25万行。最后一列,即第 9 列,包含这样的信息(请注意,这都是一列 - 其中的空格并不表示新列,而只是该列中的“数据”)

TF_binding_site_cage_181208 ZNFN1A2-91741 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_+_149850517 
TF_binding_site_cage_181208 ZNFN1A2-92447 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_-_153016326 
TF_binding_site_cage_181208 ZNFN1A2-92446 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_-_153016326 
TF_binding_site_cage_181208 ZNFN1A2-92445 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_-_153016326 
TF_binding_site_cage_181208 SNAI1-3-177789 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_+_52294530 
TF_binding_site_cage_181208 SNAI1-3-178434 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_-_52294717 
TF_binding_site_cage_181208 SNAI1-3-178161 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_-_52604408 
TF_binding_site_cage_181208 SNAI1-3-177489 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_-_52936367 
TF_binding_site_cage_181208 MEF2A,C,D-173519 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr8_+_144711658 
TF_binding_site_cage_181208 MEF2A,C,D-173496 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr8_-_145085726 
TF_binding_site_cage_181208 MEF2A,C,D-172831 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr8_+_145136211 
TF_binding_site_cage_181208 MEF2A,C,D-173254 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr9_+_696759 

基本上我正在寻找仅包含“MEF2*”的行,因此在上面的示例中,它只会选择最后 4 行。我还想要整行,而不仅仅是这一列。

我已经尝试过 awk-ing 这个,导入到 Excel,导入到 R,但有时我的方法有效,但我担心我无法“检查”是否获得了所有行。 (其中包含 MEF2 的行跨越了几千行,因此很难手动计数)。

有人能想到一种算法来帮助我提取这些行而没有(非常小的)误差范围吗?我知道这似乎是一件基本的事情,但我担心我的正则表达式技能不足以提取所有行。

答案1

这将为您提供第 9 列匹配的所有行MEF2

awk -F"\t" '$9~/MEF2/' file > output

假设你的文件是总是制表符分隔,这将起作用,您可以放心地休息。这是您所能得到的接近于 0 的误差幅度。

但是,如果您尝试导入类似 R 的内容(大概使用read.table("file",sep="\t"))并且不起作用,则可能会有一些具有不同数量字段的行(有关如何检查的信息,请参阅末尾)。如果是这样,假设您始终对最后一个字段感兴趣,则可以使用$(NF)inawk打印最后一个字段,无论有多少个字段:

awk -F"\t" '$(NF)~/MEF2/' file > output

如果您仍然觉得需要检查,您可以简单地提取所有匹配的行MEF2,无论匹配在哪里,然后比较结果:

grep MEF2 file > output2

一旦你有了它,你可以用来wc检查它们是否有相同的行数。如果没有,通过运行找出不同之处

grep -vFf output output2

该命令将打印输出 2 中不存在于输出 1 中的任何行。如果有的话,很可能他们会MEF2在队伍中的某个地方,但不在第九场。如果它位于第 9 个字段,那么您就知道您的文件不是制表符分隔的,并且您的数据有问题。


上面awk可能是最简单的解决方案,但这里有一些其他的解决方案可以做同样的事情:

  • 珀尔

    perl -F"\t" -lane '$F[8]=~/MEF2/ && print' file
    
  • sed(如果您有超过 9 个字段,这一行可能会匹配错误的行)

    sed -n '/\t.*\t.*\t.*\t.*\t.*\t.*\t.*\t.*MEF2.*/p' file
    
  • grep

    grep -P '^.+?\t.*\t.*\t.*\t.*\t.*\t.*\t.*\t.*MEF2.*' file
    

如果这些并不都产生相同的输出,那么您就知道您的文件存在问题。您还可以检查的另一件事是确保所有行都有 9 个字段。如果他们不这样做,你就知道存在问题:

awk -F"\t" 'NF!=9' file

上面的代码将打印所有不包含 9 个制表符分隔字段的行。如果有输出,则其打印的行有问题。

相关内容