我有一个看起来像这样的文件。
在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
答案 0 :(得分:0)
以下程序似乎可以满足您的需求。为方便起见,它使用DATA
文件句柄从源文件中读取数据:您必须安排打开并读取相应的数据文件。
将整个文件读入内存以便直接访问。如果文件很大(例如,数百兆字节),那么这种方法可能不合适,您将不得不回来寻求更多帮助。
记录长度不同,因此算法会找到相对于找到的前三个字母字段的相关字段。
哈希%categories
包含所有必需的文件数据。它由关键字母 - A
或B
编入索引 - 每个元素的值是包含label
(第1列)的匿名哈希数组,{{1} },以及每条记录所涵盖范围的letter
和start
。
构建输出非常简单,并使用end
和map
来查找散列中所有相关条目的“标签”。如果未找到,则会将文本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