Perl格式化csv文件并计算出现并放入行

时间:2015-08-13 18:39:23

标签: perl csv count format

我正在尝试编写一个带有csv的perl脚本,例如。

得分,ID
  1,6833
  0.508201,2759
  0.587154,2759
  0.845473,2759
  0.882188,33630

输出例如。

ID,得分,丰度
6833,1,1
2759,0.508201,0.845473,1,3
33630,0.882188,1

仅按第1列取> = 0.5的行。按第27列重复的第2列,收集其后的分数。最后一个数字是例如2759的丰度,其存在3次。

#!/usr/bin/perl
use strict;
use warnings;
open( my $csv, "$ARGV[0]" ) or die "Failed to open file: $!\n";
open( my $csv_spp, ">$ARGV[0]_spp_ML.csv" );

while ( my $line = <$csv> ) {
    my ( $ml, $id ) = split( /,/, $line );
    if ( $ml >= 0.5 ) {

        if ( $id = $id ) {
            my $count++;
        }

        print $csv_spp $id, $count;
    }
}
close($csv);
close($csv_spp);

我坚持如何让数字跟随或计算出现次数。

1 个答案:

答案 0 :(得分:3)

你的问题在这里:

if ( $id = $id ) {
    my $count++;
}

这......是胡说八道。 $count是词法范围的,所以在你“增加”它之后,它就会超出范围并再次消失。

此外,测试是否$id = $id - 即使你的意思是==你正在测试某件事是否与自己相等。 (如果你没有,你正在测试你是否可以为自己分配一些东西,这没什么意义。)

你可能意味着使用哈希计算你的出现次数,你可能需要另一个数组哈希来整理你的值。

这样的事情:

#!/usr/bin/perl
use strict;
use warnings;
open( my $csv, '<', "$ARGV[0]" ) or die "Failed to open file: $!\n";
open( my $csv_spp, '>', "$ARGV[0]_spp_ML.csv" );

my %count_of; 
my %values_of; 

while ( my $line = <$csv> ) {
    chomp; 
    my ( $ml, $id ) = split( /,/, $line );
    if ( $ml >= 0.5 ) {
        $count_of{$id}++; 
        push ( @{$values_of{$id}}, $id );
    }
}
close($csv);

foreach my $id ( sort keys %count_of ) {
   print {$csv_spp} join ( ",", $id, @{$values_of{$id}}, $count_of{$id} ),"\n";
}

close($csv_spp);

您可能还想考虑使用Text::CSV来阅读您的文件。