Perl awk——对于第一列中的每个键,搜索所有其他列并找到最小条目

Perl awk——对于第一列中的每个键,搜索所有其他列并找到最小条目,perl,awk,Perl,Awk,我有一个巨大的数据文件,看起来像这样(但有大约115列和超过400行): 对于第一列中的每个条目,我需要搜索其余的每一列,并获取以该条目开头的所有行的最小值。如果可能的话,它需要根据行和列的数量进行扩展,而不需要重新输入每个列标识符 除了excel中的min(if)之外,我还没有尝试过其他任何东西。这往往会很快中断,因为我的计算机无法处理太多的数据。我知道一点点perl和一点点awk 我正在玩弄这个,但我不知道如何将它扩展到可变数量的列 awk 'NR==1{print;next} {s[$1]

我有一个巨大的数据文件,看起来像这样(但有大约115列和超过400行):

对于第一列中的每个条目,我需要搜索其余的每一列,并获取以该条目开头的所有行的最小值。如果可能的话,它需要根据行和列的数量进行扩展,而不需要重新输入每个列标识符

除了excel中的min(if)之外,我还没有尝试过其他任何东西。这往往会很快中断,因为我的计算机无法处理太多的数据。我知道一点点perl和一点点awk

我正在玩弄这个,但我不知道如何将它扩展到可变数量的列

awk 'NR==1{print;next}
{s[$1]=!s[$1]||$2<s[$1]?$2:s[$1];t[$1]=!t[$1]||$3<t[$1]?$3:t[$1];u[$1]=!u[$1]||$4<u[$1]?$4:u[$1]}
END{for(x in s)print x,s[x],t[x],u[x]}' testing.txt
awk'NR==1{print;next}

{s[$1]=!s[$1]| |$2
NF
返回一行中的列数,您可以使用
$i
引用行
i
。如果您使用的是gawk,那么就有多维数组(对于最小的[column1][column\u number])。如果没有,您可以通过连接column1和column\u number(如下实现)来模拟它


下面是一个可能的Perl解决方案

#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'min';

my $file = 'testing.txt';
open my $fh, "<", $file or die "Unable to open '$file' $!";

my @cols = split ' ', <$fh>;

my %data;
while (<$fh>) {
    my ($key, @vals) = split;
    push @{ $data{$key} }, @vals;
}
close $fh or die $!;

while ( my ($key, $aref) = each %data) {
    printf "%-12s %s\n", $key, min(@$aref);
}

您可以在Perl中执行此操作。只需对每一行执行
split/\s+/
,然后将第一个元素用作散列的键,散列的值将是最小值。您只需在分割行时获得的数组中循环其他值,以查看是否有新的最小值。谢谢!这样做非常完美!
{
    if (NR == 1) {
        print
        next;
    }

    column1s[$1] = 1;
    for(i=2; i<=NF; i++) {
        key = i "::" $1
        if (!(key in min) || $i < min[key]) {
            min[key] = $i;
        }
    }
}

END {
    for (k in column1s) {
        row = k;

        for (i=2; i<=5; i++) {
            key = i "::" k;
            row = row "\t" min[key];
        }

        print row;
    }
}
awk -f script.awk testing.txt
#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'min';

my $file = 'testing.txt';
open my $fh, "<", $file or die "Unable to open '$file' $!";

my @cols = split ' ', <$fh>;

my %data;
while (<$fh>) {
    my ($key, @vals) = split;
    push @{ $data{$key} }, @vals;
}
close $fh or die $!;

while ( my ($key, $aref) = each %data) {
    printf "%-12s %s\n", $key, min(@$aref);
}
1:56         1.59E-02
1:34128320   8.19E-03
1:23941533   5.89E-04
1:35547072   2.18E-02
MC5R         1.17E-03
1:12418403   3.27E-03