-1

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

在 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 的初学者,因此我现在将每个条目拆分为连续的数组元素,即 for @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
4

1 回答 1

0

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

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

记录的长度各不相同,因此算法会相对于找到的第一个三字母字段来定位相关字段。

哈希%categories包含所有必需的文件数据。它由键字母(AB此处)索引,每个元素的值是一个匿名哈希数组,其中包含每个记录所涵盖范围的label(第 1 列)、the和letterthe 。startend

构建输出很简单,并使用mapgrep查找哈希中所有相关条目的“标签”。如果没有找到,"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

输出

A+80 - HELIX
A+40 - SHEET
A+202 - HELIX
B+130 - HELIX
B+268 - SHEET
B+211 - SHEET
A+35 - LOOP
于 2012-04-22T12:05:49.257 回答