我有一个包含 9 列的大文件,以制表符分隔。这个文件大约有 39MB,大约有 250,000 行。最后一列,第 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
Run Code Online (Sandbox Code Playgroud)
基本上,我正在寻找仅包含“MEF2*”的行,因此在上面的示例中,它只会选择最后 4 行。我还想要整行,而不仅仅是这一列。
我试过 awk-ing 这个,导入到 Excel,导入到 R 但有时我的方法有效,但恐怕我无法“检查”我是否得到了所有的行。(其中带有 MEF2 的行跨越几千行,因此很难手动计算)。
有人能想出一种算法来帮助我在没有(非常小的)误差范围内提取这些行吗?我知道这似乎是一件基本的事情,但恐怕我的正则表达式技能不够强大,无法提取所有行。
这将为您提供第 9 列匹配的所有行MEF2
:
awk -F"\t" '$9~/MEF2/' file > output
Run Code Online (Sandbox Code Playgroud)
假设您的文件始终以制表符分隔,这将起作用并且您可以安全地休息。这与您所获得的误差幅度一样接近 0。
但是,如果您尝试导入到 R 之类的东西(大概是使用read.table("file",sep="\t")
)但没有奏效,那么您可能会有一些字段数不同的行(有关如何检查,请参见末尾)。如果是这样,假设您始终对最后一个字段感兴趣,则可以使用$(NF)
inawk
打印最后一个字段,无论有多少个字段:
awk -F"\t" '$(NF)~/MEF2/' file > output
Run Code Online (Sandbox Code Playgroud)
如果你仍然觉得需要检查,你可以简单地提取所有匹配的行MEF2
,不管匹配在哪里,然后比较结果:
grep MEF2 file > output2
Run Code Online (Sandbox Code Playgroud)
一旦你有了它,你就可以wc
用来检查它们是否有相同的行数。如果没有,请通过运行找到它们的不同之处
grep -vFf output output2
Run Code Online (Sandbox Code Playgroud)
该命令将打印 output2 中 output1 中不存在的任何行。如果有的话,很可能他们会MEF2
在行中的某个地方,但不在第 9 个字段中。如果它在第 9 个字段中,那么您就知道您的文件不是制表符分隔的,并且您的数据有问题。
在awk
上面大概是最简单的解决方案,但这里有一些其他人做同样的事情:
珀尔
perl -F"\t" -lane '$F[8]=~/MEF2/ && print' file
Run Code Online (Sandbox Code Playgroud)sed
(如果您有 9 个以上的字段,这可能会匹配错误的行)
sed -n '/\t.*\t.*\t.*\t.*\t.*\t.*\t.*\t.*MEF2.*/p' file
Run Code Online (Sandbox Code Playgroud)grep
grep -P '^.+?\t.*\t.*\t.*\t.*\t.*\t.*\t.*\t.*MEF2.*' file
Run Code Online (Sandbox Code Playgroud)如果这些都没有产生相同的输出,您就知道您的文件存在问题。您可以检查的另一件事是确保所有行都有 9 个字段。如果他们不这样做,你就知道有一个问题:
awk -F"\t" 'NF!=9' file
Run Code Online (Sandbox Code Playgroud)
以上将打印所有不具有 9 个制表符分隔字段的行。如果有输出,它打印的行有问题。