我有一个包含 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 个制表符分隔字段的行。如果有输出,则其打印的行有问题。