从PERL中的行和列中提取信息

时间:2014-03-09 18:49:45

标签: arrays perl

我有一个包含多行和多列的巨大文件。每一行都有许多列,许多行在同一位置具有相同的名称。 E.g。

 A  C  Z  Y  X
 A  C  E  J
 B  E  K  L  M

查找在特定位置共享相同项目的所有行的最佳方法是什么?例如,我想知道有2个A,2个C,1个D等,都按列排序。

非常是Perl的新手,所以我在这方面努力奋斗,所以任何提示都会受到赞赏。

我达到了这一点:

#!/usr/local/bin/perl -w

use strict; 

my $path='My:\Path\To\My\File.txt';
my $columns;
my $line;

open (FILE,$path), print "Opened!\n" or die ("Error opening");

while (<FILE>)
{
@line=split('\t',$_);
}

close FILE;

这个输出可以是另一个TSV,只检查文件直到第5列,从上到下排序,如:

 A  2
 C  2
 Z  1
 Y  1
 E  1
 J  1
 B  1
 E  1
 K  1
 L  1

请注意,第一个项目首先出现,当在行间共享时,不会再显示后续行。

编辑:根据评论中的问题,我更改了数据集和输出。请注意,出现两个E:一个属于第三列,另一个属于第二列。

Edit2:或者,这也可以逐列分析,从而在第一列中显示结果,然后在第二列中显示结果,依此类推,只要它们清楚地分开即可。像

这样的东西
 "1st" "col"
 A 2
 B 1
 "2nd" "col"
 C 2
 E 1
 "3rd" "col"
 Z 1
 E 1
 K 1
 "4th" "col"
 Y 1
 J 1
 L 1

2 个答案:

答案 0 :(得分:1)

我没有完全理解所需输出的格式,因此下面的脚本会输出第一行第一列的所有数据,依此类推。这可以很容易地修改为您想要的格式,但它是如何首先对数据进行累积然后再处理它的快速起点。

use strict; 
use warnings;
use autodie;

my $path='My:\Path\To\My\File.txt';

open my $fh, '<', $path;

my @data;

# while (<$fh>) { Switch these lines when ready for real data
while (<DATA>) {
    my @row = split ' ';
    for my $col (0..$#row) {
        $data[$col]{$row[$col]}++;
    }
}

for my $coldata (@data) {
    for my $letter (sort keys %$coldata) {
        print "$letter $coldata->{$letter} ";
    }
    print "\n";
}

close $fh;

__DATA__
A  C  Z  Y  X
A  C  D  J
B  E  K  L  M

输出

A 2 B 1
C 2 E 1
D 1 K 1 Z 1
J 1 L 1 Y 1
M 1 X 1

答案 1 :(得分:0)

也许以下内容会有所帮助:

use strict;
use warnings;

my $path = 'My:\Path\To\My\File.txt';
my %hash;

open my $fh, '<', $path or die $!;

while (<$fh>) {
    my @cols = split ' ', $_, 5;
    $hash{$_}{ $cols[$_] || '' }++ for 0 .. 3;
}

close $fh;

for my $key ( sort { $a <=> $b } keys %hash ) {
    print "Col ", $key + 1, "\n";
    print "$_ $hash{$key}{$_}\n"
      for sort { $hash{$key}->{$b} <=> $hash{$key}->{$a} } grep $_,
      keys %{ $hash{$key} };
}

数据集输出:

Col 1
A 2
B 1
Col 2
C 2
E 1
Col 3
Z 1
K 1
E 1
Col 4
J 1
L 1
Y 1