Средние строки с тем же первым столбцом

Ваш ответ может быть найден в rsync странице справочника, под -p, --perms опция:

Таким образом, когда - перманент и - исполняемость оба отключена, поведение rsync совпадает с поведением других утилит копии файла, таких как CP (1) и tar (1).

Который похож на то, что Вы хотите, Вы на правильном пути. Я предполагаю, что Вы читаете весь раздел в странице справочника для получения полного представления того, что предлагают эти опции.

Можно отключить опцию с помощью --no-OPTION синтаксис, так отключение полномочий было бы:

rsync -a --no-perms --no-group /source /target

Можно настроить его как псевдоним в ~/.bashrc (для Ubuntu IIRC) для создания ввода легче:

alias rsync-cp='rsync -a --no-perms --no-group --progress'

и просто назовите rsync-cp вместо rsync для использования тех опций. Я включал - прогресс также для показа rsync индикаторов выполнения.

7
02.10.2015, 00:23
4 ответа

Используя awk:

Входной файл

$ cat FILE
Id  ht
510 69
510 67
510 65
510 62
510 59
601 29
601 26
601 21
601 20

Awk в оболочке:

$ awk '
    NR>1{
        arr[$1]   += $2
        count[$1] += 1
    }
    END{
        for (a in arr) {
            print "id avg " a " = " arr[a] / count[a]
        }
    }
' FILE

Или с Perl в оболочке:

$ perl -lane '
    END {
        foreach my $key (keys(%hash)) {
            print "id avg $key = " . $hash{$key} / $count{$key};
        }
    }
    if ($. > 1) {
        $hash{$F[0]}  += $F[1];
        $count{$F[0]} += 1;
    }
' FILE

Вывод:

id avg 601 = 24
id avg 510 = 64.4

И в последний раз для шутки, Perl темным запутываемая острота =)

perl -lane'END{for(keys(%h)){print"$_:".$h{$_}/$c{$_}}}($.>1)&&do{$h{$F[0]}+=$F[1];$c{$F[0]}++}' FILE
6
27.01.2020, 20:16
#!/usr/bin/perl
use strict;
use warnings;

my %sum_so_far;
my %count_so_far;
while ( <> ) {
    # Skip lines that don't start with a digit
    next if m/^[^\d]/;

    # Accumulate the sum and the count
    my @line = split();
    $sum_so_far{$line[0]}   += $line[1];
    $count_so_far{$line[0]} += 1;
}

# Dump the output
print "Id Avg.ht\n";
foreach my $id ( keys %count_so_far ) {
    my $avg = $sum_so_far{$id}/$count_so_far{$id};
    print " $id $avg\n";
}

Вывод:

ire@localhost$ perl make_average.pl input.txt 
Id Avg.ht
 510 64.4
 601 24

Обратите внимание, что Ваш демонстрационный вывод является неправильным. Нет никакого способа, которым можно добраться в среднем 52, когда каждое значение для того идентификатора равняется 59 или больше.

Кроме того, у Вас есть буква l в одном из Ваших столбцов, подменяя числом 1...

2
27.01.2020, 20:16

Смотрите на то, что сделано здесь: http://www.sugihartono.com/programming/group-by-count-and-sorting-using-perl-script/

Существенная трудная часть делает 'группу' операцией. Связанный сценарий делает то использование хеша.

В той ссылке они вычисляют сумму, но добираются, среднее число не будет сильно отличающимся.

1
27.01.2020, 20:16

С gnu datamash:

datamash -H -s -g 1 mean 2 <file
GroupBy(Id) mean()
510 64.4
601 24

Это sorts и groups by 1st field calculating 2nd field mean value, preserving Headers. Предполагается, что поля разделены одинарной табуляцией. Используйте -W, --whitespace, если они разделены несколькими пробелами или -t, --field-separator=, чтобы определить другой разделитель полей (пробел, запятая и т.д.). Поскольку datamash требует сортированного ввода, вывод будет отсортирован по сгруппированному столбцу.

2
27.01.2020, 20:16

Теги

Похожие вопросы