Как обработать дубликаты столбцов с условиями - PullRequest
1 голос
/ 26 сентября 2011

Мне нужно пропустить все строки с одним и тем же столбцом один, если столбец 2 пуст, а затем для других мне нужно рассчитать процентную долю столбца 4 по сравнению со столбцом 3?

Ввод:

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

Ответы [ 4 ]

1 голос
/ 26 сентября 2011
awk '
    NR==FNR {if (NF < 4) blank[$1]; next}
    $1 in blank {next}
    {$(NF+1) = $4/$3; print}
' datafile datafile | column -t

Поскольку теперь вы говорите, что разделитель полей является вкладкой:

awk '
    BEGIN {OFS = FS = "\t"}
    NR==FNR {if ($2 == "") blank[$1]; next}
    $1 in blank {next}
    {$5 = $4/$3; print}
' datafile datafile
1 голос
/ 26 сентября 2011

Я предполагаю, что ваши данные разделены табуляцией. Сценарий Perl примерно такой (я не проверял) ...

my @data;
my %counts;
my %blanks;
while( my $line = <STDIN> )
{
    chop($line);
    my @rec = split( "\t", $line );
    push( @data, \@rec );
    $counts{$rec[0]}++;
    if( $rec[1] eq '' )
    {
        $blanks{$rec[0]}++;
    }
}
foreach my $rec ( @data )
{
    if( $counts{$rec->[0]} <= 1 || !$blanks{$rec->[0]} )
    {
        print join( "\t", @$rec, $rec->[3] / $rec->[2] ) . "\n";
    }
}
1 голос
/ 26 сентября 2011

Как насчет:

#!/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.0303030303030303
T226PA  fg  4   2       0.5
T226PA  g   51  38      0.745098039215686
T226PA  e   41  34  0.829268292682927
1 голос
/ 26 сентября 2011

попробовать:

awk '$2 ~ /[0-9]+/{for(i in res){if ($1 ~ res[i])delete res[i]};\
rm[$1]=$1;next}\
{if($1 in rm)next;ratio=$4/$3;res[NR]=$0"\t"ratio}\
END{for (i in res)print res[i]}' file

При этом будут игнорироваться все строки, содержащие менее четырех записей, для всех остальных записей рацион рассчитывается и составляется с записью и сохранением в массиве рез. После обработки файл, записи res выводятся на стандартный вывод.

Выход:

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 Крис

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...