como subtrair o primeiro valor do último dentro de uma coluna através de uma linha no shell?

0

Eu tenho um arquivo de dados parecido com:

1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3 
2 4 5 8 9 10 13 17 19 29 30 32 33 50 700 800 900 950 

Primeiro eu quero inserir espaço entre cada 3 valores idênticos, mantendo cada três números idênticos juntos em uma coluna, olhando para a primeira linha:

1 1 1  1 1 1  1 1  2 2 2  2  3 3 3  3 3 3 
2 4 5  8 9 10  13 17  19 29 30  32  33 50 700  800 900 950

e depois eu quero subtrair o primeiro valor do último dentro de cada nova coluna na segunda linha (mas se houvesse apenas um valor em uma coluna específica (aqui a quarta coluna na segunda linha), então o último valor de a coluna anterior deve ser subtraída desse valor (32-30)), mantendo um único número fora de cada coluna da primeira linha. então os dados finais devem ser assim:

1 1 1 2 2 3 3
3 2 4 11 2 667 150 

alguma sugestão por favor? Enquanto isso, devo mencionar que meus dados reais são de fato enormes e quero agrupar cada 5 valores únicos na primeira linha. Eu posso querer mudar o tamanho do grupo. Então, eu preciso que o script seja flexível ...

    
por zara 29.01.2016 / 14:45

2 respostas

4

Perl para o resgate!

#!/usr/bin/perl
use warnings;
use strict;

my $group_size = 3;

my @first = split ' ', <>;

my @groups;
my $start_index = 0;
while ($start_index < @first) {
    my $step = 1;
    while ( $step < $group_size
            && $start_index + $step < @first
            && $first[$start_index] == $first[ $start_index + $step ]
          ) {
        ++$step;
    }
    push @groups, $step;
    print $first[$start_index], ' ';
    $start_index += $step;
}
print "\n";

my @numbers = split ' ', <>;

my $last;
for my $size (@groups) {
    my @group = splice @numbers, 0, $size;
    my $value = $group[-1] - $group[0];
    $value = $group[0] - $last if 1 == $size;
    $last = $group[-1];
    print $value, ' ';
}
print "\n";

Você não especificou o que deve acontecer se o primeiro grupo tiver apenas um membro.

    
por 29.01.2016 / 15:22
1

Isso é semelhante à resposta da choroba

$ cat file
1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3 
2 4 5 8 9 10 13 17 19 29 30 32 33 50 700 800 900 950 

$ perl -ane '
    if ($. == 1) {
        for (($n,$i,$j) = (1,0,0); $j < @F; $n++, $j++) {
            if ($n == 3 || $F[$j] != $F[$j+1]) {
                $i-- if $i == $j;
                push @pairs, [$i, $j];
                $n = 0;
                $i = $j + 1;
            }
        }
        printf "%d ", $F[ $_->[1] ] for @pairs;
    }
    else {
        printf "%d ", $F[ $_->[1] ] - $F[ $_->[0] ] for @pairs;
    }
    print "\n";
' < file
1 1 1 2 2 3 3 
3 2 4 11 2 667 150 

Para a primeira linha de entrada ($. == 1) , ele calcula a lista de pares de índices nos quais você está interessado. Isso se aplica a:

[[0, 2], [3, 5], [6, 7], [8, 10], [10, 11], [12, 14], [15, 17]]
    
por 29.01.2016 / 23:02

Tags