Perl 如何处理具有条件的重复列

Perl 如何处理具有条件的重复列,perl,shell,awk,Perl,Shell,Awk,如果第2列为空,我需要跳过第1列的所有行,然后对于其他行,我需要计算第4列相对于第3列的百分比 T245P rr 8 1 0.125 T245P rr 33 1 0.03030303 T226PA fg 4 2 0.5 T226PA g 51 38 0.745098039 T226PA e 41 34 0.829268293 输入: T75PA 2 0 T75PA kk 4 1 T240P

如果第2列为空,我需要跳过第1列的所有行,然后对于其他行,我需要计算第4列相对于第3列的百分比

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
输入:

T75PA       2   0   
T75PA   kk  4   1   
T240P       4   3   
T240P   test    3   3   
T240P   test2   3   1   
T245P   rr  8   1   
T245P   rr  33  1   
T226PA  fg  4   2   
T226PA  g   51  38  
T226PA  e   41  34
T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
输出

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
尝试:

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
这将忽略少于四个条目的所有行, 对于所有其他条目,计算并连接配给 使用entrie,并在处理 文件中,res的条目被打印到stdout

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
输出:

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
T245P   rr  8   1       0.125
T245P   rr  33  1       0.030303
T226PA  fg  4   2       0.5
T226PA  g   51  38      0.745098
T226PA  e   41  34          0.829268
HTH Chris

试试:

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
这将忽略少于四个条目的所有行, 对于所有其他条目,计算并连接配给 使用entrie,并在处理 文件中,res的条目被打印到stdout

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
输出:

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
T245P   rr  8   1       0.125
T245P   rr  33  1       0.030303
T226PA  fg  4   2       0.5
T226PA  g   51  38      0.745098
T226PA  e   41  34          0.829268

HTH Chris

我假设您的数据是分开的。类似这样的perl脚本(我还没有测试过它)

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
my@数据;
我的百分比计算;
我的%空白;
while(我的$line=)
{
印章(行);
my@rec=split(“\t”,美元行);
推送(@data,\@rec);
$counts{$rec[0]}++;
如果($rec[1]等式“”)
{
$blanks{$rec[0]}++;
}
}
foreach my$rec(@data)
{
如果($counts{$rec->[0]}[0]})
{
打印联接(“\t”,@$rec,$rec->[3]/$rec->[2])。“\n”;
}
}

我假设您的数据是用制表符分隔的。类似这样的perl脚本(我还没有测试过它)

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
my@数据;
我的百分比计算;
我的%空白;
while(我的$line=)
{
印章(行);
my@rec=split(“\t”,美元行);
推送(@data,\@rec);
$counts{$rec[0]}++;
如果($rec[1]等式“”)
{
$blanks{$rec[0]}++;
}
}
foreach my$rec(@data)
{
如果($counts{$rec->[0]}[0]})
{
打印联接(“\t”,@$rec,$rec->[3]/$rec->[2])。“\n”;
}
}
那么:

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
#!/usr/bin/perl
use Modern::Perl;


my $re = qr/^([A-Z0-9]+)\s+?(\S+|\s+)\s+(\d+)\s+(\d+)\s*$/;
my $skip = '';
while (<DATA>) {
    chomp;
    if (my @l = $_ =~ /$re/) {
        if ($l[1] =~ /^\s+$/ || $skip eq $l[0]) {
            $skip = $l[0];
            next;
        }
        $skip = '';
        my $r = $l[3] / $l[2];
        say "$_\t$r";
    }
}

__DATA__
T75PA       2   0   
T75PA   kk  4   1   
T240P       4   3   
T240P   test    3   3   
T240P   test2   3   1   
T245P   rr  8   1   
T245P   rr  33  1   
T226PA  fg  4   2   
T226PA  g   51  38  
T226PA  e   41  34
那么:

T245P   rr  8   1   0.125
T245P   rr  33  1   0.03030303
T226PA  fg  4   2   0.5
T226PA  g   51  38  0.745098039
T226PA  e   41  34  0.829268293
#!/usr/bin/perl
use Modern::Perl;


my $re = qr/^([A-Z0-9]+)\s+?(\S+|\s+)\s+(\d+)\s+(\d+)\s*$/;
my $skip = '';
while (<DATA>) {
    chomp;
    if (my @l = $_ =~ /$re/) {
        if ($l[1] =~ /^\s+$/ || $skip eq $l[0]) {
            $skip = $l[0];
            next;
        }
        $skip = '';
        my $r = $l[3] / $l[2];
        say "$_\t$r";
    }
}

__DATA__
T75PA       2   0   
T75PA   kk  4   1   
T240P       4   3   
T240P   test    3   3   
T240P   test2   3   1   
T245P   rr  8   1   
T245P   rr  33  1   
T226PA  fg  4   2   
T226PA  g   51  38  
T226PA  e   41  34

awk'{hsh[$1]=hsh[$0]}END{for(i in hsh){split(i,a,“\t”);if(a[2]!=”)打印a[4]a[3]}'awk'{hsh[$1]=hsh[$0]}END{for(i in hsh){split i,a,“\t”);if(a[2]!=”)打印a[4]a[3]}“如果在匹配行之前出现空白行,就应该排除这些行。是否有可能专门寻找第二个空白?”NeBee:是的,我改变了答案。现在它检查第二列是否包含数字。如果是这样,则第二列必须缺失。如果在匹配行之前出现空白行,则应该排除这些行。是否可以具体地查找列两个空白?@ NeBee:是的,我更改了答案。现在它检查第二列是否包含数字。谢谢:我稍微修改了一下,只检查第二列
awk-F“\t”'NR==FNR{If($2==”){blank[$1];next}}$1在blank{next}{$(NF+1)=$4/$3;print}'
谢谢:我稍微修改了一下,只检查第二列
awk-F“\t”'NR==FNR{If($2==”){blank[$1];next}$1在blank{next}$1)=$4/$3;打印}'