免费注册 查看新帖 |

Chinaunix

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

文件匹配相同ID根据比较结果输出ID和匹配项——求大神赐教... [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-05-19 08:10 |只看该作者 |倒序浏览
本帖最后由 little_joe 于 2016-05-19 08:55 编辑

文件a:
>A
1
2
3
4
>B
1
2
3
4
>C
1
2
3
4
文件b:
ID   start     end
>D      2         5
>C      1         3
>F      3         5
>A      4         7
如果文件a与文件b匹配到相同的ID,
例如文件a:>A匹配到文件b:>A,
则比较A下面的数字是不是在[4,7]即文件b的start到end区间内,
如果在区间内则输出ID和该数字如:
>A
4
>C
1
2
3
perl刚入门,有些茫然,向各路大神求助


论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
2 [报告]
发表于 2016-05-19 09:30 |只看该作者
本帖最后由 sunzhiguolu 于 2016-05-19 09:50 编辑

回复 1# little_joe
你试下,
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my ($sID, $sBegin, $sEnd, %hData, $sCnt);
  5. while (<>){
  6.     s/\A\s+|\s+\z//g;
  7.     if (@ARGV){
  8.         if (++$sCnt % 5 == 1){
  9.             $sID = $_;
  10.             next;
  11.         }
  12.         push (@{$hData{$sID}[0]}, $_);
  13.         next;
  14.     }

  15.     next if (!m/\A>/);
  16.     ($sID, $sBegin, $sEnd) = split;
  17.     push (@{$hData{$sID}[1]}, $sBegin, $sEnd) if (exists $hData{$sID});
  18. }

  19. foreach $sID (sort keys %hData){
  20.     next if (@{$hData{$sID}} < 2);
  21.     local $, = $/;
  22.     my @aInterval = @{$hData{$sID}[-1]};
  23.     print $sID, grep {$_ >= $aInterval[0] and $_ <= $aInterval[-1]} @{$hData{$sID}[0]};
  24.     print "\n";
  25. }
复制代码
>A
4
>C
1
2
3


   

论坛徽章:
0
3 [报告]
发表于 2016-05-19 09:45 |只看该作者
非常感谢您的帮助,跪拜大神 回复 2# sunzhiguolu


   

论坛徽章:
0
4 [报告]
发表于 2016-05-19 12:25 |只看该作者
本帖最后由 little_joe 于 2016-05-19 12:30 编辑

上面的例子结果是没有问题的,可是像下面这样的例子就比较乱了
文件a:
>NP_414809.1
61
84
>NP_415044.4
47
76
79
93
360
366
387
391
398
429
468
483
>NP_415045.1
5
14
21
88
107
116
164
191
206
252
323
329
344
>NP_415069.1
48
51
64
93
236
251
263
324
343
文件b:
      ID               start   end
>NP_414557.1  122    146
>NP_414562.1    2     26
>NP_414563.1    2     60
>NP_414570.1   284    316
>NP_414798.1    2     26
>NP_414799.1    2     60
>NP_414808.1    2     26
>NP_414809.1    2     60
>NP_414824.1  523    547
>NP_414841.1  423    475
>NP_414897.1  349    398
>NP_414994.1  52    124
>NP_415044.4   2     46
>NP_415069.1   2     47
>NP_415114.1  122   146
运行程序后会出现

用文件a匹配文件b打印匹配项但没有匹配上的数字
用文件b匹配文件a会有数字输出但结果也比较乱,不知道是怎么回事,还希望大神能够指导指导,
还有请问怎样改一下输出会以文件形式而不是直接打印呢?

论坛徽章:
0
5 [报告]
发表于 2016-05-19 12:28 |只看该作者
本帖最后由 little_joe 于 2016-05-19 12:33 编辑

上面的例子结果是没有问题的,可是像下面这样的例子就比较乱了
文件a:
>NP_414809.1
61
84
>NP_415044.4
47
76
79
93
360
366
387
391
398
429
468
483
>NP_415045.1
5
14
21
88
107
116
164
191
206
252
323
329
344
>NP_415069.1
48
51
64
93
236
251
263
324
343
文件b:
      ID               start   end
>NP_414557.1  122    146
>NP_414562.1    2     26
>NP_414563.1    2     60
>NP_414570.1   284    316
>NP_414798.1    2     26
>NP_414799.1    2     60
>NP_414808.1    2     26
>NP_414809.1    2     60
>NP_414824.1  523    547
>NP_414841.1  423    475
>NP_414897.1  349    398
>NP_414994.1  52    124
>NP_415044.4   2     46
>NP_415069.1   2     47
>NP_415114.1  122   146
运行程序后会出现

用文件a匹配文件b打印匹配项但没有匹配上的数字
用文件b匹配文件a会有数字输出但结果也比较乱,不知道是怎么回事,还希望大神能够指导指导,
还有请问怎样改一下输出会以文件形式而不是直接打印呢?回复 2# sunzhiguolu


   

论坛徽章:
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
6 [报告]
发表于 2016-05-19 13:53 |只看该作者
回复 5# little_joe

$ perl get_range.pl
Usage  : get_range.pl Gene_file range_file
Example: get_range.pl gen.txt rng.txt

$ perl get_range.pl gen.txt rng.txt

$ cat get_range.pl

use strict;
use warnings;

sub message{
  print <<EOF;
Usage  : $0 Gene_file range_file
Example: $0 gen.txt rng.txt
EOF
  print "@_" if "@_";
  exit 1;
}

message() if(@ARGV != 2);

my ($FLgen, $FLrng) = @ARGV;

open(my $FHgen, "<", $FLgen) or die "can't open $FLgen\n";
open(my $FHrng, "<", $FLrng) or die "can't open $FLrng\n";

my %hRange;
while(<$FHrng>){
  s/^\s+|\s+$//g;
  next if(m/^(#|$)/);
  next if(! m/^>/);
  my ($sID, $sStart, $sEnd) = split;
  $hRange{$sID} = {"S"=>$sStart, "E"=>$sEnd};
}

my $sID    = "";
my $sPrint = 0;
while(<$FHgen>){
  s/^\s+|\s+$//g;
  next if(m/^(#|$)/);
  if(m/^(>\S+)/){
    $sID = $1;
    $sPrint = 0;
    next;
  }
  next if(! exists $hRange{$sID});
  if(m/^\d+$/){
    if($hRange{$sID}{"S"} <= $_ && $_ <= $hRange{$sID}{"E"}){
      print "$sID\n" if($sPrint==0);
      print "$_\n";
      $sPrint = 1;
    }
  }
}

   

评分

参与人数 2信誉积分 +15 收起 理由
little_joe + 5
sunzhiguolu + 10 又学了一手, 谢谢大神指点!!!

查看全部评分

论坛徽章:
6
15-16赛季CBA联赛之新疆
日期:2016-03-22 22:34:5915-16赛季CBA联赛之山东
日期:2016-04-11 09:08:41程序设计版块每日发帖之星
日期:2016-06-28 06:20:00程序设计版块每日发帖之星
日期:2016-07-19 06:20:00每日论坛发贴之星
日期:2016-07-19 06:20:0015-16赛季CBA联赛之青岛
日期:2016-07-20 22:44:17
7 [报告]
发表于 2016-05-19 14:33 |只看该作者
本帖最后由 RE_HASH 于 2016-05-19 14:52 编辑

5楼数据没结果。

$> cat aa bb |perl -076ne 'if (/(NP\S+)/) {$k=$1; $t = (/\d +\d/) ? "range":"values"; @{$O->{$k}->{$t}}=/\s(\d+)/g;}END{$,="\n";for $k (sort keys %$O) {print ">$k" , @vv , "\n" if (@vv = grep{$_ >= $O->{$k}->{range}->[0] && $_<=$O->{$k}->{range}->[1]} @{$O->{$k}->{values}}); }}' > result.txt

评分

参与人数 1信誉积分 +10 收起 理由
sunzhiguolu + 10 这条大 if 太长了, 我滴个上帝呀!

查看全部评分

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
8 [报告]
发表于 2016-05-19 15:30 |只看该作者
本帖最后由 sunzhiguolu 于 2016-05-19 16:33 编辑

回复 5# little_joe
不好意思, 考虑的较少. 试下这个,
perl abc.pl a b>ab
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my ($sID, $sBegin, $sEnd, %hData);
  5. while (<>){
  6.     s/\A\s+|\s+\z//g;
  7.     if (@ARGV){
  8.         if (m/\A>/){
  9.             $sID = $_;
  10.             next;
  11.         }
  12.         push (@{$hData{$sID}[0]}, $_);
  13.         next;
  14.     }
  15.     next if (!m/\A>/);
  16.     ($sID, $sBegin, $sEnd) = split;
  17.     push (@{$hData{$sID}[1]}, $sBegin, $sEnd) if (exists $hData{$sID});
  18. }

  19. foreach $sID (sort grep {$#{$hData{$_}}} keys %hData){
  20.     ($sBegin, $sEnd) = @{$hData{$sID}[-1]};
  21.     if ($sBegin <= $hData{$sID}[0][0] and $sEnd >= $hData{$sID}[0][0]){
  22.         local $, = $/;
  23.         print $sID, grep {$_ >= $sBegin and $_ <= $sEnd} @{$hData{$sID}[0]};
  24.         print "\n";
  25.     }
  26. }
复制代码

评分

参与人数 1信誉积分 +5 收起 理由
little_joe + 5

查看全部评分

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
9 [报告]
发表于 2016-05-19 16:20 |只看该作者
回复 6# jason680
大神, 您这个绝对简单易懂, 这条语句太给力了 $hRange{$sID} = {"S"=>$sStart, "E"=>$sEnd};!!!

   

论坛徽章:
0
10 [报告]
发表于 2016-05-19 19:48 |只看该作者
是我的问题,刚开始没说清楚, 再次感谢!!回复 8# sunzhiguolu


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP