免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: little_joe
打印 上一主题 下一主题

’求助!!!求助!!!文件匹配输出特定的内容‘ [复制链接]

论坛徽章:
0
21 [报告]
发表于 2016-06-17 18:41 |只看该作者
这些冗余数据可以去掉的,不好意思,一开始我没想到是不是应该去掉,还有每个文件A对应的ID匹配文件B后需要读取该ID下面的所有Query和Sbjct行,如果对应的Sbjct行不是字母是‘-'的话就忽略,麻烦您了回复 20# sunzhiguolu


   

论坛徽章:
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
22 [报告]
发表于 2016-06-17 18:47 |只看该作者
回复 21# little_joe
请看下 19 楼, 我的问题.

   

论坛徽章:
0
23 [报告]
发表于 2016-06-17 21:15 |只看该作者
第二行的内容不是Query行的衔接,它们是没有关系的,第二行其实是Query行和Sbjct行的关系描述,+表示两个氨基酸是同义氨基酸,这是生物学相关的问题,所以读取文件B时不用考虑第二行,只需要考虑以Query和Sbjct开头的行就行。
文件B中如您所标黄色的序号不会出现大的在前,小的在后的情况,因为氨基酸序列是连续的有顺序的。
因为每个Query行开头都会有一个数字序号,如果文件A中的数字小于文件BQuery第一个数字,那么便可以直接忽略,即如果文件A数字不在该区间内即可忽略,
如果文件A为35则直接忽略以2开头的Query行,只读取含有35的Query行回复 19# sunzhiguolu


   

论坛徽章:
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
24 [报告]
发表于 2016-06-17 22:05 |只看该作者
回复 23# little_joe
好的, 如有不明白 我再问.

   

论坛徽章:
0
25 [报告]
发表于 2016-06-17 22:18 |只看该作者
恩恩,您辛苦啦!谢谢!回复 24# sunzhiguolu


   

论坛徽章:
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
26 [报告]
发表于 2016-06-18 13:49 |只看该作者
本帖最后由 sunzhiguolu 于 2016-06-18 14:01 编辑

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

  4. sub collect_data{
  5.     my (%ha, %hFilt, $id);
  6.     open (my $fhA, '<', shift);
  7.     while (defined (local $_ = <$fhA>)){
  8.         if (/\A(\D\S+)/){
  9.             %hFilt = () if (!exists $ha{$1});
  10.             $id = $1;
  11.             next;
  12.         }
  13.         s/\s+\z//;
  14.         push (@{$ha{$id}}, $_) if (!$hFilt{$_}++);
  15.     }
  16.     close ($fhA);
  17.     \%ha;
  18. }

  19. sub compare{
  20.     my ($id, $rh, @aData) = (@_);
  21.     my %hStat;
  22.     foreach my $v (@{$rh->{$id}}){
  23.         foreach my $V (grep {$v >= $_->[0] && $v <= $_->[2] and $v >= $_->[3] && $v <= $_->[-1]} @aData){
  24.             my ($q1, $q2, $q3, $s1, $s2, $s3) = @$V;
  25.             my @aChars = split //, ($s2 =~ s/-//gr);
  26.             $hStat{$aChars[$v - $s1]}++;
  27.         }
  28.     }
  29.     if (%hStat){
  30.         print "$id\n";
  31.         print "$_:$hStat{$_}\n" for keys %hStat;
  32.     }
  33. }

  34. my $rha = collect_data (shift);

  35. open (my $fh, '<', shift);
  36. my ($Flag, $Offset, $ID, @aData) = 0;
  37. while (defined (local $_ = <$fh>)){
  38.     next if (/\A\s*\z/ or !/\A(?:Query|Sbjct)/);
  39.     if (/\AQuery=\h+(\S+)/){
  40.         compare ($ID, $rha, splice (@aData)) if (@aData);
  41.         exists ($rha->{$1}) ? do {($ID, $Flag, $Offset) = ($1, 1, -1)} : ($Flag = 0);
  42.         next;
  43.     }
  44.     next if (!$Flag);
  45.     if (/\A(Query|Sbjct)\h+(\d+)\h+(\H+)\h+(\d+)/){
  46.         $Offset++ if ($1 eq "Query");
  47.         push (@{$aData[$Offset]}, $2, $3, $4);
  48.     }
  49. }
  50. close ($fh);
  51. compare ($ID, $rha, splice (@aData)) if ($Flag);
复制代码
perl abc.pl a b
----------------------------------------------------------------------------------------------
NP_414894.2-1
M:4
NP_415921.2-1
M:4
YP_025310.1-1
A:2
YP_026163.2-1
M:4
YP_002791252.1-1
C:1
NP_417338.3-1
M:4
NP_417516.3-1
M:4
NP_418692.2-1
M:4
NP_418697.1-1
L:1
H:1



   

论坛徽章:
6
丑牛
日期:2014-03-21 15:42:04子鼠
日期:2014-04-12 11:50:17处女座
日期:2014-09-01 09:25:1115-16赛季CBA联赛之吉林
日期:2015-12-22 14:01:5215-16赛季CBA联赛之广东
日期:2016-03-08 18:49:422016科比退役纪念章
日期:2016-07-06 12:19:55
27 [报告]
发表于 2016-06-18 16:34 |只看该作者
本帖最后由 stanley_tam 于 2016-06-18 16:36 编辑

感觉我的结果不一样
  1. #!perl
  2. use strict;
  3. use warnings;

  4. package Sequence;

  5. sub new {
  6.     my ($class, $id) = @_;

  7.     my $self             = +{};
  8.     $self->{'id'}        = $id;
  9.     $self->{'members'}   = [];

  10.     bless $self, $class;
  11.     return $self;
  12. }

  13. sub add_member {
  14.     my ($self, $member) = @_;
  15.     push @{ $self->{'members'} }, $member;
  16. }

  17. sub get_members {
  18.     my ($self) = @_;
  19.     return @{ $self->{'members'} };
  20. }

  21. sub get_id {
  22.     my ($self) = @_;
  23.     return $self->{'id'};
  24. }

  25. 1;

  26. package SequenceCollection;

  27. sub new {
  28.     my ($class)                = @_;
  29.     my $self                   = +{};
  30.     $self->{'sequences'}       = [];
  31.     $self->{'_id_seq'}         = +{};
  32.     $self->{'last_seen_id'}    = q{};
  33.     $self->{'is_duplicate_id'} = 0;

  34.     bless $self, $class;
  35.     return $self;
  36. }

  37. sub process_line {
  38.     my ($self, $line) = @_;

  39.     $line =~ s{\s}{}gmix;
  40.     return if not $line;

  41.     if ($line =~ m{^ \d+ $}mix) {
  42.         return if $self->{'is_duplicate_id'};
  43.         my $last_seen_id = $self->{'last_seen_id'};
  44.         my $sequence     = $self->{'_id_seq'}->{$last_seen_id};
  45.         $sequence->add_member($line);
  46.     }
  47.     else {
  48.         $self->{'last_seen_id'} = $line;


  49.         if (exists $self->{'_id_seq'}->{$line}) {
  50.             $self->{'is_duplicate_id'} = 1;
  51.         }
  52.         else {
  53.             # new record
  54.             $self->{'is_duplicate_id'} = 0;

  55.             my $sequence = Sequence->new($line);
  56.             $self->{'_id_seq'}->{$line} = $sequence;

  57.             push @{$self->{'sequences'}}, $sequence;
  58.         }
  59.     }
  60. }

  61. sub get_sequences {
  62.     my ($self) = @_;
  63.     return @{ $self->{'sequences'} };
  64. }

  65. 1;

  66. package Query;

  67. sub new {
  68.     my ($class, $id)                  = @_;
  69.    
  70.     my $self                          = +{};
  71.     $self->{'id'}                     = $id;
  72.     $self->{'query_list'}             = [];
  73.     $self->{'subject_list'}           = [];
  74.     $self->{'last_seen_start_number'} = undef;

  75.     bless $self, $class;
  76.     return $self;
  77. }

  78. sub populate_list {
  79.     my ($self, $string_type, $string, $start_number) = @_;

  80.     my @letters = split //, $string;

  81.     if ($string_type eq 'Query') {
  82.         my $query_list = $self->{'query_list'};
  83.         $self->{'last_seen_start_number'} = $start_number;

  84.         for my $letter (@letters){
  85.             $query_list->[$start_number] = $letter;
  86.             ++$start_number;
  87.         }

  88.         $self->{'query_list'} = $query_list;
  89.     }
  90.     elsif ($string_type eq 'Sbjct') {
  91.         my $subject_list = $self->{'subject_list'};
  92.         $start_number = $self->{'last_seen_start_number'};

  93.         for my $letter (@letters){
  94.             $subject_list->[$start_number] = $letter;
  95.             ++$start_number;
  96.         }

  97.         $self->{'subject_list'} = $subject_list;
  98.     }
  99.     else {
  100.         die "This shouldn't happen...$/";
  101.     }
  102. }

  103. sub get_subject_character {
  104.     my ($self, $number) = @_;
  105.     my $subject_list    = $self->{'subject_list'};
  106.     my $character       = $subject_list->[$number] // q{};
  107.     return $character
  108. }

  109. 1;

  110. package QueryCollection;

  111. sub new {
  112.     my ($class, $id)          = @_;
  113.    
  114.     my $self                  = +{};
  115.     $self->{'queries'}        = [];
  116.     $self->{'id_query'}       = +{};
  117.     $self->{'last_seen_id'}   = undef;

  118.     bless $self, $class;
  119.     return $self;
  120. }

  121. sub process_line {
  122.     my ($self, $line) = @_;
  123.     $line             =~ s{^\s+ | \s+$}{}gmix;

  124.     return if not $line;

  125.     if ($line =~ m{Query=}) {
  126.         my ($id)                = $line =~ m{^Query= \s* (.*)$}mx;
  127.         $self->{'last_seen_id'} = $id;

  128.         my $query = Query->new($id);

  129.         push @{ $self->{'queries'} }, $query;
  130.         $self->{'id_query'}->{$id}  = $query;
  131.     }
  132.     elsif ($line =~ m{Query \s+ \d+ \s+}mix){
  133.         my $last_seen_id            = $self->{'last_seen_id'};
  134.         my $query                   = $self->{'id_query'}->{$last_seen_id};
  135.         my ($start_number, $string) = $line =~ m{^Query \s+ (\d+) \s+ (\S+) \s+}mx;
  136.         my $string_type             = 'Query';
  137.         $query->populate_list($string_type, $string, $start_number);
  138.     }
  139.     elsif ($line =~ m{Sbjct \s+ \d+ \s+}mix){
  140.         my $last_seen_id            = $self->{'last_seen_id'};
  141.         my $query                   = $self->{'id_query'}->{$last_seen_id};
  142.         my ($start_number, $string) = $line =~ m{^Sbjct \s+ (\d+) \s+ (\S+) \s+}mx;
  143.         my $string_type             = 'Sbjct';
  144.         $query->populate_list($string_type, $string, $start_number);
  145.     }
  146. }

  147. sub get_query_by_id {
  148.     my ($self, $id) = @_;
  149.     my $query       = $self->{'id_query'}->{$id} || q{};
  150.     return $query;
  151. }

  152. sub get_subject_character {
  153.     my ($self, $id, $number) = @_;
  154.     my $character            = q{};
  155.    
  156.     my $query                = $self->get_query_by_id($id);

  157.     if ($query) {
  158.         $character = $query->get_subject_character($number);
  159.     }

  160.     return $character;
  161. }

  162. 1;

  163. package main;


  164. sub main {
  165.     my $sequence_collection = SequenceCollection->new();
  166.     open my $a_fh, '<', 'A.word';
  167.     while (defined(my $line = readline $a_fh)) {
  168.         $sequence_collection->process_line($line);
  169.     }
  170.     close $a_fh;


  171.     my $query_collection = QueryCollection->new();
  172.     open my $b_fh, '<', 'B.word';
  173.     while (defined(my $line = readline $b_fh)) {
  174.         $query_collection->process_line($line);
  175.     }
  176.     close $b_fh;


  177.     for my $sequence ( $sequence_collection->get_sequences() ){
  178.         my @members = $sequence->get_members();
  179.         my $id          = $sequence->get_id();

  180.         my %count = ();
  181.         for my $number ( @members ){
  182.             my $character = $query_collection->get_subject_character($id, $number);
  183.             ++$count{$character};
  184.         }

  185.         print "$/id => [$id]$/";
  186.         print "members => [@members]$/";
  187.         for my $character (keys %count){
  188.             my $number = $count{$character};
  189.             print "character => [$character]$/";
  190.             print "number => [$number]$/";
  191.         }

  192.     }

  193. }

  194. main();


  195. __END__
复制代码
输出:
  1. id => [NP_414894.2-1]
  2. members => [77]
  3. character => [-]
  4. number => [1]

  5. id => [NP_415088.1-1]
  6. members => [134]
  7. character => [W]
  8. number => [1]

  9. id => [NP_415560.1-1]
  10. members => [137]
  11. character => [S]
  12. number => [1]

  13. id => [NP_415921.2-1]
  14. members => [77]
  15. character => [-]
  16. number => [1]

  17. id => [YP_025310.1-1]
  18. members => [73 78]
  19. character => [T]
  20. number => [1]
  21. character => [V]
  22. number => [1]

  23. id => [YP_026163.2-1]
  24. members => [77]
  25. character => [-]
  26. number => [1]

  27. id => [YP_588459.1-1]
  28. members => [62 63]
  29. character => [N]
  30. number => [1]
  31. character => [K]
  32. number => [1]

  33. id => [YP_002791252.1-1]
  34. members => [26]
  35. character => [S]
  36. number => [1]

  37. id => [NP_417338.3-1]
  38. members => [77]
  39. character => [-]
  40. number => [1]

  41. id => [NP_417516.3-1]
  42. members => [77]
  43. character => [-]
  44. number => [1]

  45. id => [NP_418692.2-1]
  46. members => [77]
  47. character => [-]
  48. number => [1]

  49. id => [NP_418697.1-1]
  50. members => [81 85]
  51. character => [W]
  52. number => [1]
  53. character => [E]
  54. number => [1]
复制代码

论坛徽章:
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
28 [报告]
发表于 2016-06-18 17:20 |只看该作者
stanley_tam 发表于 2016-06-18 16:34
感觉我的结果不一样输出:

差异之处, 比如:
A 文件:
NP_415088.1-1
134

对应 B 文件 Query= NP_415088.1-1
...
Query  134  W  134
            W
Sbjct  61   W  61
...
Query  134  W  134
            W
Sbjct  61   W  61
...
Query  134  W  134
            W
Sbjct  61   W  61

A 与 B 中的对应数值 134 在 B 中的 Query 134 W 134 中满足匹配要求, 但是其下的 Sbjct 61 W 61 行的 却不能满足 A 中数值 134 的匹配范围.
在这里我采用的是 双过滤 即 A 中的 134 必须在 B 中 Query, Sbjct 行中都满足要求才认为满足要求,  这一点可能需要楼主说明一下. (这个地方我的确拿不准)

论坛徽章:
0
29 [报告]
发表于 2016-06-18 18:20 |只看该作者
本帖最后由 little_joe 于 2016-06-18 18:40 编辑

谢谢各位的关注和帮助,是我之前没说明白的原因,文件A的数值134其实是不用满足Sbjct的条件的,这里134的作用是找到对应Query行的对应字母,然后通过该字母(Query行)找到Sbjct行中Query行字母对应的字母(也就是其下方对应的字母),输出的是Sbjct行的字母,并且对这个输出的字母进行计数,文件中当Query行中出现“-”时不会影响序号区间例如:Query:1 ASDFGHJKL 9和Query:1  ASD-FGHJKL 9它们两个都是包含9个元素,“-”不会影响字母的序号,而当Query行是字母对应的Sbjct行是“-”时则不用输出例如:Query:1 ASDFGHJKL 9
                                                        Sbjct:1 ASD-FGHJK 8假设文件A数值为4,则找到了Query行的F此时Sbjct行对应“-”则可以不用输出(或者为了简单期间输出计数也可)这个应该是文件的输出结果(例子中较少,所以手动验证了一下)
NP_415088.1-1          W:4       
NP_415560.1-1                S:1       
YP_025310.1-1                S:1        V:1
NP_418697.1-1                W:7        V:7
YP_588459.1-1                N:1        K:1
YP_002791252.1-1        S:1       
回复 28# sunzhiguolu


   

论坛徽章:
0
30 [报告]
发表于 2016-06-18 18:29 |只看该作者
谢谢您,我之前有可能没说清楚,文件中当Query行中出现“-”时不会影响序号区间例如:Query:1 ASDFGHJKL 9和Query:1  ASD-FGHJKL 9它们两个都是包含9个元素,“-”不会影响字母的序号例如:Query:1  ASDF-GHJKL  9
                                            Sbjct:6  ASDFGIHLUL  16这时候Query行出现了“-”要是文件A数值为6时,则找到的Query行字母应该为H,对应的输出是Sbjct行的H,回复 27# stanley_tam


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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP