我正在尝试处理以下文件:
http://bioinfo.mc.vanderbilt.edu/TSGene/Human_716_TSGs.txt
...由700多条记录组成,每条记录有11个制表符分隔字段。每个记录由相同的重复类别组成,即GeneID,Gene_symbol,Alias,Xref,Chromosome,Cytoband,Full_name,Gene_type,Description,Nucleotide_Sequence和Protein_Sequence。我想提取所有的GeneIDs(所有记录中的第一个字段),所有的cytobands,以及所有的蛋白质序列,并构建一个复杂的数据结构,例如:
$genes->{$gene_name}{$cytoband} = $protein_sequence;
我的问题是我只能抓住第一条记录(11个字段)并将它们分配到列表中。我不知道如何捕获和存储构成一列的所有字段。我最初的尝试如下:
use strict;
use warnings;
use autodie;
my ($gene, $symbol, $alias, $xref,
$chromo, $cytoband, $full_name, $gene_type, $desc, $nuc_seq, $pro_seq);
open FH, '<', 'human_tsgs.txt';
my @data = do {local $/; <FH>};
close FH;
for (@data)
{
($gene, $symbol, $alias, $xref, $chromo, $cytoband,
$full_name, $gene_type, $desc, $nuc_seq, $pro_seq) = split "\t", $_;
#print $gene, "\n";
}
任何有建设性的反馈都会受到赞赏。
谢谢!
凯特琳
答案 0 :(得分:4)
问题在于您阅读文件的方式。您可以通过在块中$/
取消local
来取消定义$/
。
以下是发生的事情:
undef
the input line seperator为@data
,则会将整个文件读为一行。 for
只有一个包含整个文件的元素。 $_
循环中迭代它时,您将获得split
中的整个文件。 value_row1_11\nvalue_row2_1
将为您提供所有字段(尽管第11个字段应为print $gene
。$/
,这是第一个值。您需要做的是逐行读取文件。没有必要干涉open my $fh, '<', 'human_tsgs.txt' or die $!;
while ( my $line = <$fh> ) {
chomp $line;
my ( $gene, $symbol, $alias, $xref, $chromo, $cytoband, $full_name,
$gene_type, $desc, $nuc_seq, $pro_seq ) = split "\t", $line;
}
close $fh;
。
{{1}}
如果您在某些时候有更大的文件,逐行读取它也更适合内存处理。如果您啜饮整个文件,则需要将其存储在内存中。这样,您只需要一次存储一行来处理数据。
实现此目的的另一种方法是使用Text::CSV模块。
答案 1 :(得分:3)
而不是
my @data = do {local $/; <FH>};
你需要这些:
my @data = <FH>;
chomp @data;
#now you have all lines in the @data array
答案 2 :(得分:1)
这个程序可以满足您的需求。我将Data :: Dumper的输出重定向到文本文件o33.txt。
我使用了命令行: perl t9.pl Human_716_TSGs.txt&gt; o33.txt 强>
(t9.pl是以下程序)
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV_XS;
use autodie;
my $csv = Text::CSV_XS->new ( { binary => 1, eol => "\n", sep_char => "\t" } );
my %genes;
while (my $row = $csv->getline (*ARGV)) {
my ($gene, $cytoband, $protein_sequence) = @$row[0, 5, 10];
next unless $gene =~ /^\d+$/; # eliminate header and final line
$genes{$gene}{$cytoband} = $protein_sequence;
}
use Data::Dumper; print Dumper \%genes;
更新:看看genid(第一个字段)是如何唯一的(并且您确定它们将是唯一的),您可能需要不同的结构,如:
$genes{$gene} = {cytoband => $cytoband, protein_sequence => $protein_sequence};