Arhn - архитектура программирования

Суммировать столбец и количество строк

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

файл1

36  2605 1 2
36  2605 1 2
36  2603 1 2
36  2605 1 2
36  2605 1 2
36  2605 1 2
36  2606 1 2

Желаемый результат

2603  36 1  2 1
2605 180 5 10 5
2606  36 1  2 1

Я пытался

awk '{a[$2]+=$1}{b[$2]+=$3}{c[$2]+=$4;count[$2]+=$2}END{for(i in a)print i,a[i],b[i],c[i],count[i]}' file1

заранее спасибо

awk
21.04.2019

Ответы:


1

Переименовали переменные и добавили красивую печать:

awk '
{
    sum1[$2]+=$1
    sum3[$2]+=$3
    sum4[$2]+=$4
    count[$2]++

    len2=((l=length($2))>len2?l:len2)        
    len1=((l=length(sum1[$2]))>len1?l:len1)
    len3=((l=length(sum3[$2]))>len3?l:len3)
    len4=((l=length(sum4[$2]))>len4?l:len4)
    len5=((l=length(sum5[$2]))>len5?l:len5)
}
END {
    for(i in count) {
        printf "%*d %*d %*d %*d %*d\n",
            len2,i,len1,sum1[i],len3,sum3[i],len4,sum4[i],len5,count[i]
    }
}' file

Выход:

2603  36 1  2 1
2605 180 5 10 5
2606  36 1  2 1
21.04.2019

2

Пробелы в наши дни относительно недороги, вам действительно следует подумать о том, чтобы получить их для своего кода, особенно если вы хотите, чтобы другие люди читали его, чтобы помочь вам в его отладке! Вот код, который вы разместили:

awk '{a[$2]+=$1}{b[$2]+=$3}{c[$2]+=$4;count[$2]+=$2}END{for(i in a)print i,a[i],b[i],c[i],count[i]}' file1

и вот он после прогонки через улучшитель кода (я использовал gawk -o):

{
        a[$2] += $1
}

{
        b[$2] += $3
}

{
        c[$2] += $4
        count[$2] += $2
}

END {
        for (i in a) {
                print i, a[i], b[i], c[i], count[i]
        }
}

Посмотрите, как простое добавление некоторого пробела теперь значительно упрощает понимание, и поэтому ошибка в том, как заполняется count[$2], явно очевидна? Некоторые осмысленные имена переменных также всегда чрезвычайно полезны, и я слышал, что буквенно-цифровые символы сейчас на особом счету!

FWIW вот как я бы это сделал:

$ cat tst.awk
BEGIN { keyFldNr = 2 }
{
    numOutFlds = 0
    for (i=1; i<=NF; i++) {
        if (i != keyFldNr) {
            sum[$keyFldNr,++numOutFlds] += $i
        }
    }
    cnt[$keyFldNr]++
}
END {
    for (key in cnt) {
        printf "%s%s", key, OFS
        for (i=1; i<=numOutFlds; i++) {
            printf "%s%s", sum[key,i], OFS
        }
        print cnt[key]
    }
}

$ awk -f tst.awk file
2603 36 1 2 1
2605 180 5 10 5
2606 36 1 2 1

$ awk -f tst.awk file | column -t
2603  36   1  2   1
2605  180  5  10  5
2606  36   1  2   1

Обратите внимание, что он будет работать как есть, независимо от того, сколько полей у вас есть в каждой строке, и если вам нужно использовать другое поле для ключа, который вы считаете и суммируете, вы просто измените значение keyFldNr в разделе BEGIN с 2 на то, что вы хотите, чтобы это было.

21.04.2019
  • ценю ваш совет 21.04.2019
  • Эд Мортон, спасибо за все объяснения и код. Ценю вашу помощь в этом 22.04.2019

  • 3

    Подход без awk, использующий очень полезный массив данных GNU, который предназначен для таких задач, как Вот этот:

    $ datamash -Ws groupby 2 sum 1,3,4 count 2 < input.txt
    2603    36  1   2   1
    2605    180 5   10  5
    2606    36  1   2   1
    

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

    21.04.2019

    4

    Вы почти угадали, вы не увеличиваете count[$2] должным образом.

    $ awk '{a[$2]+=$1;b[$2]+=$3;c[$2]+=$4;count[$2]++}
      END{for(i in a) print i,a[i],b[i],c[i],count[i]}' file
    2603 36 1 2 1
    2605 180 5 10 5
    2606 36 1 2 1
    
    21.04.2019

    5

    нет необходимости во внешней программе, быстрее ~ 21 мс, пробовал на чистом gnu awk

    awk '{if($0~/^[A-Za-z0-9]/)a[NR]=$2" "$1" "$3" "$4}END{asort(a);$0="";for(;i++<NR;){split(a[i],b);if($1==""||b[1]==$1){$2+=b[2];$3+=b[3];$4+=b[4];$5++} else {print;$2=b[2];$3=b[3];$4=b[4];$5=1} $1=b[1]} print}' file1
    
    22.04.2019
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..