Perl / Linux使用另一个文件的内容过滤大文件
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Perl / Linux使用另一个文件的内容过滤大文件,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2613字,纯文字阅读大概需要4分钟。
内容图文
![Perl / Linux使用另一个文件的内容过滤大文件](/upload/InfoBanner/zyjiaocheng/967/4dd231439d014b46b3aaa6b19a58224e.jpg)
我正在使用另一个较小文件的内容过滤580 MB文件.
File1(较小的文件)
chr start End
1 123 150
2 245 320
2 450 600
File2(大文件)
chr pos RS ID A B C D E F
1 124 r2 3 s 4 s 2 s 2
1 165 r6 4 t 2 k 1 r 2
2 455 t2 4 2 4 t 3 w 3
3 234 r4 2 5 w 4 t 2 4
如果满足以下条件,我想从File2捕获行.
File2.Chr == File1.Chr&& File2.Pos> File1.Start&& File2.Pos< File1.End
我尝试过使用awk但它运行得非常慢,我也想知道是否有更好的方法来实现相同的目标?
谢谢.
这是我正在使用的代码:
#!/usr/bin/perl -w
use strict;
use warnings;
my $bed_file = "/data/1000G/Hotspots.bed";#File1 smaller file
my $SNP_file = "/data/1000G/SNP_file.txt";#File2 larger file
my $final_file = "/data/1000G/final_file.txt"; #final output file
open my $in_fh, '<', $bed_file
or die qq{Unable to open "$bed_file" for input: $!};
while ( <$in_fh> ) {
my $line_str = $_;
my @data = split(/\t/, $line_str);
next if /\b(?:track)\b/;# skip header line
my $chr = $data[0]; $chr =~ s/chr//g; print "chr is $chr\n";
my $start = $data[1]-1; print "start is $start\n";
my $end = $data[2]+1; print "end is $end\n";
my $cmd1 = "awk '{if(\$1==chr && \$2>$start && \$2</$end) print (\"chr\"\$1\"_\"\$2\"_\"\$3\"_\"\$4\"_\"\$5\"_\"\$6\"_\"\$7\"_\"\$8)}' $SNP_file >> $final_file"; print "cmd1\n";
my $cmd2 = `awk '{if(\$1==chr && \$2>$start && \$2</$end) print (\"chr\"\$1\"_\"\$2\"_\"\$3\"_\"\$4\"_\"\$5\"_\"\$6\"_\"\$7\"_\"\$8)}' $SNP_file >> $final_file`; print "cmd2\n";
}
解决方法:
将小文件读入数据结构并检查其他文件的每一行.
在这里,我将其读入一个数组,每个元素都是一个带有一行字段的arrayref.然后根据此数组中的arrayrefs检查数据文件的每一行,比较每个要求的字段.
use warnings 'all';
use strict;
my $ref_file = 'reference.txt';
open my $fh, '<', $ref_file or die "Can't open $ref_file: $!";
my @ref = map { chomp; [ split ] } grep { /\S/ } <$fh>;
my $data_file = 'data.txt';
open $fh, '<', $data_file or die "Can't open $data_file: $!";
# Drop header lines
my $ref_header = shift @ref;
my $data_header = <$fh>;
while (<$fh>)
{
next if not /\S/; # skip empty lines
my @line = split;
foreach my $refline (@ref)
{
next if $line[0] != $refline->[0];
if ($line[1] > $refline->[1] and $line[1] < $refline->[2]) {
print "@line\n";
}
}
}
close $fh;
这将从提供??的样本中打印出正确的行.它允许多行匹配.如果这不可能,请在if块中添加last,以便在找到匹配后退出foreach.
关于代码的一些评论.如果更多可能有用,请告诉我.
在阅读参考文件时,< $fh>在列表上下文中使用它以返回所有行,并且grep过滤掉空行. map首先选择换行符,然后通过[]生成一个arrayref,其中元素是split获得的行上的字段.输出列表分配给@ref.
当我们重用$fh时,它首先被关闭(如果它是打开的),所以不需要关闭.
我存储标题行,也许是打印或检查.我们真的只需要排除它们.
内容总结
以上是互联网集市为您收集整理的Perl / Linux使用另一个文件的内容过滤大文件全部内容,希望文章能够帮你解决Perl / Linux使用另一个文件的内容过滤大文件所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。