请原谅我在没有任何编码努力的情况下提问。但对我来说似乎太难了。
我有一个数据文件,其中tab分为三个数据列(以及一些重复的标题行):
Sequence ../Output/yy\Programs\NP_416485.4 alignment. Using default output format...
# ../Output/Split_Seq/NP_415931.4.fasta -- js_divergence - window_size: 3
# jjhgjg cstr score
0 0.89 u-p
1 -5.79 ---
2 0.85 yui
3 0.51 uio
4 0.66 -08
Sequence ../Output/yy\Programs\YP_986467.7 alignment. Using default output format...
# ../Output/Split_Seq/YP_986467.7.fasta -- js_divergence - window_size: 3
# jjhgjg cstr score
0 0.001 -s-
1 0.984 ---
2 0.564 -fg
3 0.897 -sr
从第二个数据列开始,对于那些大于0.5的值,我想提取相应的第一个列号(或范围)。
对于上面的输入,输出将是:
NP_416485.4: 1, 3-5
YP_986467.7: 2-4
这里,“NP_416485.4”和“YP_986467.7”来自头描述符(在\ Programs之后)。 (注意,例如,“NP_416485.4”的实际值应为“NP_416485.4:0,2-4”,但我将所有值都增加为+1,因为我不想以0开头)。
感谢您的考虑。我将不胜感激任何帮助。谢谢
答案 0 :(得分:1)
你并没有真正对问题做出很好的描述,而你自己也没有做出任何努力来解决问题,但这是解决问题第一部分的方法(解析问题)归档到数据结构中)。您需要遍历%results
哈希并生成所需的输出。
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Data::Dumper;
my %results;
my $section;
while (<DATA>) {
# Look for a new section
if (/\\Programs\\(\S+)\s/) {
$section = $1;
}
# Look for data lines
if (/^\d\b/) {
my @data = split;
if ($data[1] > 0.5) {
push @{$results{$section}}, $data[0] + 1;
}
}
}
say Dumper \%results;
__DATA__
Sequence ../Output/yy\Programs\NP_416485.4 alignment. Using default output format...
# ../Output/Split_Seq/NP_415931.4.fasta -- js_divergence - window_size: 3
# jjhgjg cstr score
0 0.89 u-p
1 -5.79 ---
2 0.85 yui
3 0.51 uio
4 0.66 -08
Sequence ../Output/yy\Programs\YP_986467.7 alignment. Using default output format...
# ../Output/Split_Seq/YP_986467.7.fasta -- js_divergence - window_size: 3
# jjhgjg cstr score
0 0.001 -s-
1 0.984 ---
2 0.564 -fg
3 0.897 -sr
答案 1 :(得分:1)
这是一种方法。如果您在Unix机器上有DOS数据文件,我使用\r?\n
来匹配新行,因此它适用于所有情况:
use feature qw(say);
use strict;
use warnings;
my $file_name = 'input.txt';
open ( my $fh, '<', $file_name ) or die "Could not open file '$file_name': $!";
my $str = do { local $/; <$fh> };
close $fh;
my @chunks = $str =~ /(Sequence(?:.(?!Sequence))*)/sg;
my %ids;
for my $cstr ( @chunks ) {
my ( $id, $data ) = $cstr
=~/Split_Seq\/(\S+)\.fasta.*?\r?\n\r?\n(.*)$/s;
my @lines = split /\n/, $data;
my @vals;
for my $line ( @lines ) {
my @fields = split " ", $line;
push ( @vals, $fields[0] + 1 ) if $fields[1] > 0.5;
}
$ids{$id} = \@vals;
}
for my $id ( keys %ids ) {
my @tmp = sort { $a <=> $b } @{ $ids{$id} };
my ( $first, $last );
my @rr;
for my $i (0..$#tmp) {
if ( $i == 0 ) {
$first = $tmp[0];
$last = undef;
}
if ( $i < $#tmp && ($tmp[$i] == ($tmp[$i+1] - 1 )) ) {
$last = $tmp[$i+1];
next;
}
if ( defined $last ) {
push @rr, "$first-$last";
$last = undef;
}
else {
push @rr, $tmp[$i];
}
$first = ( $i < $#tmp ) ? $tmp[$i+1] : undef;
}
say "$id: ", join ",", @rr;
}
<强>输出:强>
NP_416485.4: 1,3-5
YP_986467.7: 2-4