免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 6909 | 回复: 21
打印 上一主题 下一主题

请教一个关于范围操作符(..)的问题 [复制链接]

论坛徽章:
1
金牛座
日期:2013-09-06 08:50:31
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-09-04 08:10 |只看该作者 |倒序浏览
假如我有一个文件A,里面有2列,B列是排好序的,如下:

aaba 1
aabb 2
aabc 3
bbbb 5
bbbc 7
bbbd 8
    .
    .
    .
zdab 1000000

怎么样用范围操作符来统计有多少行的第二列数在(5,100)之间?  我只记得 范围操作符像一个电子开关。但是不知道具体在代码中应该怎么运用。
  1. #usr/bin/perl
  2. use strict;
  3. my ($a,$b)=(5,10);
  4. my $num;
  5. while(__DATA__){
  6.         ...
  7. }

  8. __DATA__
  9. aaba 1
  10. aabb 2
  11. aabc 3
  12. bbbb 5
  13. bbbc 7
  14. bbbd 8
  15.     .
  16.     .
  17.     .
  18. zdab 1000000
复制代码

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
2 [报告]
发表于 2013-09-04 09:23 |只看该作者
那种模式的 .. 没学过 shell 理解不了就算了不是不可替代的,只要知道在 scalar context 下 .. 的行为是不一样的就行了。

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
3 [报告]
发表于 2013-09-04 10:15 |只看该作者
本帖最后由 jason680 于 2013-09-04 10:18 编辑

回复 1# 飞越地平线

How about this, control by yourself ...

# perl tt.pl
aabb 2
aabc 3
bbbb 5

# cat tt.pl
#usr/bin/perl
use strict;
use warnings;

my ($sMin,$sMax)=(2, 5);

while(<DATA>){
  my $sNum = (split)[1];

  # stop condition
  last if($sNum > $sMax);

  # start condition
  if($sNum >= $sMin){
    print;
    next;
  }
}

__DATA__
aaba 1
aabb 2
aabc 3
bbbb 5
bbbc 7
bbbd 8

论坛徽章:
1
金牛座
日期:2013-09-06 08:50:31
4 [报告]
发表于 2013-09-04 10:50 |只看该作者
回复 2# zhlong8

想到范围操作符是因为我遇到了这样一个问题:

我有2个目录,目录A和目录B,
目录A有多个文件,每个文件像这样:
chr1 3 7 aa
chr2 4 9 bb
chr1 8 10 cc
chr3 13 15 dd

目录B有多个文件(文件名为chr1, chr2, chr3),比如chr1文件内的内容像这样:
chr1 1
chr1 2
chr1 3
chr1 5
chr1 7
chr1 8
chr1 9
chr1 9
chr1 10
chr1 11
    .
    .
    .
chr1 1000000

我想计算对于每一条(chr1 3 7 aa),计算chr1文件里第二列在(3,7)之间的行数,比如这里是行数是3。

因此按照一般的思维,我先glob得到目录A的和目录B的全部文件。对于输入目录A的文件的每一行,搜索目录B,然后统计输出。但是这样程序运行时间太久了,所以我想到了2个办法不知道能不能增加效率。

1. 对于每一条比如(chr1 3 7 aa),循环一行一行读入目录B里的文件chr1,若第二列数字大于7则跳出循环。
2. 对于目录A里的多个文件,可否同时进行循环统计?这个是不是和多线程有关,想请教下应该怎么做?或者有没有更好的方法?

谢谢!

论坛徽章:
1
金牛座
日期:2013-09-06 08:50:31
5 [报告]
发表于 2013-09-04 10:52 |只看该作者
回复 3# jason680

嗯。我刚也想到了这个。
但是我想有没有更进一步提高效率的方法。具体的问题描述在4楼。
   

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
6 [报告]
发表于 2013-09-04 11:13 |只看该作者
回复 4# 飞越地平线


    前年应该帮一个妹子做过类似的,数据量比较大内存不够跑得超慢,用的是 Perl+XS 解决的就是用 C 写最耗时和内存的部分。Perl 足够快了,但是简单的数字运算字节码和一条机器指令还是有着几个数量级的差距的。

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
7 [报告]
发表于 2013-09-04 12:19 |只看该作者
回复 5# 飞越地平线

where is your code?
   

论坛徽章:
1
金牛座
日期:2013-09-06 08:50:31
8 [报告]
发表于 2013-09-04 14:42 |只看该作者
本帖最后由 飞越地平线 于 2013-09-04 14:43 编辑

回复 7# jason680

如下,写的不好看。
目录B下的文件名称是像bed_chr_1.bed, bed_chr_2.bed这样的。
  1. #usr/bin/perl
  2. use warnings;
  3. use strict;
  4. my ($dir, $dir2);
  5. my %fdir;
  6. my %fh;
  7. $dir = "G:\\Data";
  8. $dir2 = "G:\\排序后文件";
  9. my $test = "G:\\test";
  10. $dir = $test;
  11. my @file = glob "$dir\\*";
  12. my @bed = glob "$dir2\\*";
  13. #哈希%fdir存储键值对(名称,路径)。哈希%fh存储键值对(名称,文件句柄)。
  14. map { my $name = $_; $name =~ s/.*bed_(.+)_(.+)\.bed/$1$2/; $fdir{$name} = $_;} @bed;
  15. map {open $fh{$_},"<",$fdir{$_} or die "Can't open file $_!\n"; } keys %fdir;

  16. for my $in(@file){
  17.         open IN,"<","$in" or die "Can't open $in!\n";
  18.         my @array;
  19.         map {chomp;next if(/^\s*$/);push @array,[split('\t',$_)]} <IN>;
  20.         close IN;
  21.         open OUT,">","$in.snp";
  22.         for my $gene(@array){                              #@array记录目录A下的文件(文件不大)
  23.                 print OUT $gene->[3];                                                        #    $gene->[3]为每行的名称;根据$gene->[0]来确定要打开目录B下的具体哪个文件;($gene->[1],$gene->[2])就是($min,$max)。
  24.                 next unless ($gene->[0] =~ /chr/g);
  25.                 next unless(exists $fh{$gene->[0]});                               
  26.                 my $filehandle = $fh{$gene->[0]};
  27.                 seek $filehandle,0,0;
  28.                 my $num=0;
  29.                 while(<$filehandle>){                         #文件句柄$filehandle为目录B下文件的文件句柄。
  30.                         next if index($_,$gene->[0])== -1;
  31.                         chomp;
  32.                         my @array2 = split '\t',$_;
  33.                         last if ($gene->[2] < $array2[2]);
  34.                         $num++ if ($gene->[0] eq $array2[0] and $array2[2]>=$gene->[1]);      #这里统计符合条件的行数。
  35.                 }
  36.                 print OUT "\t".$num."\n";
  37.         }
  38.        
  39.         close OUT;
  40. }
复制代码

论坛徽章:
1
金牛座
日期:2013-09-06 08:50:31
9 [报告]
发表于 2013-09-04 14:59 |只看该作者
感觉看起来挺麻烦复杂的。。
我的笔记本是2G内存。实验室有12G、处理器i7的电脑。
回复 6# zhlong8


   

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
10 [报告]
发表于 2013-09-04 21:24 |只看该作者
回复 9# 飞越地平线


    为什么不把 @bed 文件夹里的内容全存到变量里提前处理好格式?直接操作数组比你每次一行一行读快的多吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP