Макс., Среднее, Мин. для диапазона в столбце данных

set -eили set -o errexitне применяется к командам, которые являются частью условий, как в:

if cmd; do
until cmd; do
while cmd; do
cmd || whatever
cmd && whatever

Это относится и к ловушке ERRдля поддерживающих ее снарядов.

Итак, идиоматический способ игнорировать неудачу команды —:

cmd || : errors ignored

Или просто:

cmd || true
cmd || :

Это отменяет set -eдля этого cmdвызова, а также устанавливает $?на 0 (на значение :/ true, когда cmdтерпит неудачу)

cmd && true
ret=$?

Также отменяет set -e, но сохраняет статус выхода cmd.

0
03.01.2020, 16:42
5 ответов

В одну сторону:

sort -k4n,4 file | awk '$2>=43808877 && $2<=43808882{tot+=$4;cnt++;max=$4;min=cnt==1?$4:min}END{print min, max,tot/cnt}'

Во-первых, мы sortфайл на 4-м столбце, чтобы 1-я запись имела мин, а последняя макс. Используя awk, мы суммируем числа в диапазоне и печатаем статистику

2
28.01.2020, 02:21

В этом случае кажется целесообразным разделить задачу на 2 процесса :один для выбора записей с учетом диапазона в 2 доллара, второй для генерации статистики:

awk '43808877 <= $2 && $2 <= 43808882' file |
awk '
    NR == 1 {min = max = $4}
    $4 < min {min = $4}
    $4 > max {max = $4}
    {sum += $4}
    END {
        if (NR) printf "%d\n%d\n%f\n", min, max, sum / NR
    }
'
0
28.01.2020, 02:21

Урезанная версия.

$ awk '/43808877/,/43808882/{t+=$4;c++;if($4>x){x=$4}if($4<n||!length(n)){n=$4}}END{print x,n,t/c}' f
14 3 8.83333
$
0
28.01.2020, 02:21
$ cat tst.awk
$2>=43808877 && $2<=43808882 {
    cnt++
    sum += $4
    min = ( (cnt == 1) || ($4 < min) ? $4 : min )
    max = ( (cnt == 1) || ($4 > max) ? $4 : max )
}
END {
    print max+0
    print min+0
    print (cnt ? sum / cnt : 0)
}

$ awk -f tst.awk file
14
3
8.83333

Обратите внимание на защиту в разделе END, чтобы убедиться, что вы всегда получаете числовой вывод и не получаете ошибку деления на ноль, даже если в нужном диапазоне нет записей.

0
28.01.2020, 02:21

Если вы не женаты на awk, то Миллер хорош для таких вещей:

mlr --nidx --repifs filter '$2 >= 43808877 && $2 <= 43808882' then stats1 -f 4 -a max,min,mean file
1
28.01.2020, 02:21

Теги

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