Perl匹配文件跨文件

时间:2012-04-22 10:49:41

标签: perl

我有一个看起来像这样的文件。

在Perl代码中,我使用的是数组@query = ('A+80', 'A+40', 'A+202', 'B+130', 'B+268', 'B+211', 'A+35'); 我想要做的是:对于数组的每个元素,扫描下面显示的文件中的行并打印出这样的内容:

A+80 - HELIX

A+40 - SHEET

A+202 - HELIX

B+130 - HELIX

B+268 - SHEET

B+211 - SHEET

A+35 - LOOP

此输出背后的逻辑是提取阵列中的每个条目,第一部分即A或B,以及第二部分,即与第一部分相关的数字。考虑数组中的第一个条目:A+80。在文件的第三行,数字80位于78(第6列)和90(第9列)之间,并且第一个字母A在两种情况下也匹配。因此,程序会打印此查询的HELIX。

考虑第二个元素:A+40。第二部分,即数字位于此行的范围

SHEET    2   B 3 ARG A  37  VAL A  43  1

即。在第7列和第10列中列出的数字之间,字母也匹配。因此,对于此条目,输出为:SHEET

对于其他情况,例如B+211。下面给出的行匹配数字和与之关联的字母。

SHEET    2   B 3 ARG A  37  VAL A  43  1

因此,此条目的输出为:SHEET

此外,对于与其关联的字母和数字的条目,不匹配文件中的任何行。代码输出:A+35 - LOOP

在Perl中执行此操作的有效方法是什么? 因为我是Perl的初学者,所以我现在将每个条目分成连续的数组元素,即@query,并将字母和数字与行中的每个相关列进行匹配/比较。但不知怎的,我无法获得所需的输出。

请帮忙......

HELIX    1   1 GLY A    9  GLN A   30  1                                  
HELIX    2   2 ASP A   47  ILE A   63  1                                  
HELIX    3   3 GLU A   78  GLU A   90  1                                  
HELIX    4   4 THR A  111  ALA A  117  1                                  
HELIX    5   5 PRO A  120  LYS A  122  5                                  
HELIX    6   6 SER A  129  ARG A  137  1                                  
HELIX    7   7 CYS A  147  THR A  159  1                                  
HELIX    8   8 GLY A  178  ASN A  188  1                                  
HELIX    9   9 LEU A  202  LYS A  208  1                                  
HELIX   10  10 GLY A  224  TRP A  226  5                                  
HELIX   11  11 TYR A  258  GLU A  263  1                                  
HELIX   12  12 VAL A  275  PHE A  294  1                                  
HELIX   13  13 GLY B    9  GLN B   30  1                                  
HELIX   14  14 ASP B   47  ILE B   63  1                                  
HELIX   15  15 GLU B   78  GLU B   90  1                                  
HELIX   16  16 THR B  111  ALA B  117  1                                  
HELIX   17  17 PRO B  120  LYS B  122  5                                  
HELIX   18  18 SER B  129  ARG B  137  1                                  
HELIX   19  19 CYS B  147  THR B  159  1                                  
HELIX   20  20 GLY B  178  TRP B  187  1                                  
HELIX   21  21 LEU B  202  LYS B  208  1                                  
HELIX   22  22 GLY B  224  TRP B  226  5                                  
HELIX   23  23 TYR B  258  GLU B  263  1                                  
HELIX   24  24 GLY B  276  PHE B  294  5                                  
SHEET    1   A 2 GLU A   5  LEU A   7  0                                        
SHEET    2   A 2 PHE A 267  THR A 269  1  
SHEET    1   B 3 LYS A  66  LEU A  72  0                                        
SHEET    2   B 3 ARG A  37  VAL A  43  1  
SHEET    3   B 3 GLY A  96  VAL A  99  1  
SHEET    1   C 4 THR A 191  CYS A 195  0                                        
SHEET    2   C 4 HIS A 167  VAL A 171  1  
SHEET    3   C 4 ILE A 211  VAL A 214  1  
SHEET    4   C 4 ILE A 232  ASP A 235  1             
SHEET    1   D 2 GLU B   5  LEU B   7  0                                        
SHEET    2   D 2 PHE B 267  THR B 269  1  
SHEET    1   E 3 LYS B  66  LEU B  72  0                                        
SHEET    2   E 3 ARG B  37  VAL B  43  1  
SHEET    3   E 3 GLY B  96  VAL B  99  1  
SHEET    1   F 4 THR B 191  CYS B 195  0                                        
SHEET    2   F 4 HIS B 167  VAL B 171  1  
SHEET    3   F 4 ILE B 211  VAL B 214  1  
SHEET    4   F 4 ILE B 232  ASP B 235  1  
SHEET    1   G 2 ASN B 239  PRO B 242  0                                        
SHEET    2   G 2 ARG B 250  VAL B 253 -1

1 个答案:

答案 0 :(得分:0)

以下程序似乎可以满足您的需求。为方便起见,它使用DATA文件句柄从源文件中读取数据:您必须安排打开并读取相应的数据文件。

将整个文件读入内存以便直接访问。如果文件很大(例如,数百兆字节),那么这种方法可能不合适,您将不得不回来寻求更多帮助。

记录长度不同,因此算法会找到相对于找到的前三个字母字段的相关字段。

哈希%categories包含所有必需的文件数据。它由关键字母 - AB编入索引 - 每个元素的值是包含label(第1列)的匿名哈希数组,{{1} },以及每条记录所涵盖范围的letterstart

构建输出非常简单,并使用endmap来查找散列中所有相关条目的“标签”。如果未找到,则会将文本grep添加为默认值。

"LOOP"

输出

use strict;
use warnings;

my @query = qw/ A+80 A+40 A+202 B+130 B+268 B+211 A+35 /;

my %categories;

while (<DATA>) {
  next unless /\S/;
  my @data = split;
  my @indices = grep $data[$_] =~ /^[A-Z]{3}$/, 0 .. $#data;
  my %info;
  @info{qw/ label letter start end /} = @data[ 0, $indices[0]+1, $indices[0]+2, $indices[1]+2 ];
  push @{ $categories{$info{letter}} }, \%info;
}

for my $item (@query) {
  my ($letter, $value) = split /\+/, $item;
  my @matches = map $_->{label},
      grep { $value >= $_->{start} and $value <= $_->{end} }
      @{ $categories{$letter} };
  @matches = ('LOOP') unless @matches;
  warn qq(Multiple categories for query "$item") unless @matches == 1;
  printf "%s - %s\n", $item, $_ for @matches 
}

__DATA__
HELIX    1   1 GLY A    9  GLN A   30  1                                  
HELIX    2   2 ASP A   47  ILE A   63  1                                  
HELIX    3   3 GLU A   78  GLU A   90  1                                  
HELIX    4   4 THR A  111  ALA A  117  1                                  
HELIX    5   5 PRO A  120  LYS A  122  5                                  
HELIX    6   6 SER A  129  ARG A  137  1                                  
HELIX    7   7 CYS A  147  THR A  159  1                                  
HELIX    8   8 GLY A  178  ASN A  188  1                                  
HELIX    9   9 LEU A  202  LYS A  208  1                                  
HELIX   10  10 GLY A  224  TRP A  226  5                                  
HELIX   11  11 TYR A  258  GLU A  263  1                                  
HELIX   12  12 VAL A  275  PHE A  294  1                                  
HELIX   13  13 GLY B    9  GLN B   30  1                                  
HELIX   14  14 ASP B   47  ILE B   63  1                                  
HELIX   15  15 GLU B   78  GLU B   90  1                                  
HELIX   16  16 THR B  111  ALA B  117  1                                  
HELIX   17  17 PRO B  120  LYS B  122  5                                  
HELIX   18  18 SER B  129  ARG B  137  1                                  
HELIX   19  19 CYS B  147  THR B  159  1                                  
HELIX   20  20 GLY B  178  TRP B  187  1                                  
HELIX   21  21 LEU B  202  LYS B  208  1                                  
HELIX   22  22 GLY B  224  TRP B  226  5                                  
HELIX   23  23 TYR B  258  GLU B  263  1                                  
HELIX   24  24 GLY B  276  PHE B  294  5                                  
SHEET    1   A 2 GLU A   5  LEU A   7  0                                        
SHEET    2   A 2 PHE A 267  THR A 269  1  
SHEET    1   B 3 LYS A  66  LEU A  72  0                                        
SHEET    2   B 3 ARG A  37  VAL A  43  1  
SHEET    3   B 3 GLY A  96  VAL A  99  1  
SHEET    1   C 4 THR A 191  CYS A 195  0                                        
SHEET    2   C 4 HIS A 167  VAL A 171  1  
SHEET    3   C 4 ILE A 211  VAL A 214  1  
SHEET    4   C 4 ILE A 232  ASP A 235  1             
SHEET    1   D 2 GLU B   5  LEU B   7  0                                        
SHEET    2   D 2 PHE B 267  THR B 269  1  
SHEET    1   E 3 LYS B  66  LEU B  72  0                                        
SHEET    2   E 3 ARG B  37  VAL B  43  1  
SHEET    3   E 3 GLY B  96  VAL B  99  1  
SHEET    1   F 4 THR B 191  CYS B 195  0                                        
SHEET    2   F 4 HIS B 167  VAL B 171  1  
SHEET    3   F 4 ILE B 211  VAL B 214  1  
SHEET    4   F 4 ILE B 232  ASP B 235  1  
SHEET    1   G 2 ASN B 239  PRO B 242  0                                        
SHEET    2   G 2 ARG B 250  VAL B 253 -1