Суммируйте значения в повторяющихся строках, используя Bash - PullRequest
0 голосов
/ 20 июня 2020

Я видел разные версии этого вопроса в Stack Overflow, но не встречал ни одной, которая бы касалась этого конкретного варианта использования.

Цель

Найти повторяющиеся строки на основе всего строка (не только один столбец), кроме значения в последнем столбце. Удалите все повторяющиеся строки, кроме одной, но сначала просуммируйте значения в последнем столбце каждого дубликата и покажите полученное значение в последнем столбце оставшейся повторяющейся строки. Я хотел бы сделать это в Bash.

Пример использования

У меня есть таблица каждой страницы на веб-сайте и количество полученных ею просмотров, а также некоторые другие метаданные . Однако некоторые строки в таблице представляют одну и ту же страницу, только с разным количеством просмотров. Эти просмотры необходимо суммировать, чтобы отобразить просмотры за все время для каждой страницы.

Пример

Исходный файл:

url,title,tag,version,guide,views
"https://website.com/1-1/section/product/page-title","Page Title 1",tag-1,"1-1","guide-1",100
"https://website.com/2-2/section/product/page-title","Page Title 2",tag-2,"2-2","guide-2",5
"https://website.com/1-1/section/product/page-title","Page Title 1",tag-1,"1-1","guide-1",15
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",10
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",20
"https://website.com/4-4/section/product/page-title","Page Title 4",tag-4,"4-4","guide-4",7
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",30

Требуемый файл:

url,title,tag,version,guide,views
"https://website.com/1-1/section/product/page-title","Page Title 1",tag-1,"1-1","guide-1",115
"https://website.com/2-2/section/product/page-title","Page Title 2",tag-2,"2-2","guide-2",5
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",60
"https://website.com/4-4/section/product/page-title","Page Title 4",tag-4,"4-4","guide-4",7

Я хотел бы здесь поделиться каждой итерацией скрипта, которую я пробовал, и разбить, что сработало, а что нет. Это так над моей головой, что я изо всех сил пытаюсь сделать это. Мой процесс заключался в том, чтобы использовать части ответов на аналогичные вопросы о переполнении стека (все они были в awk, что имеет смысл для меня) и изменить сравниваемый столбец. Но поскольку в некоторых ответах сравнивается только один столбец, результаты моих изменений непоследовательны и странны. Скрипты достаточно сложны, и я изо всех сил пытаюсь понять, почему.

Может ли кто-нибудь дать образование о том, как go найти ответ, или пример, который указывает мне правильное направление? Спасибо, если да.

Ответы [ 3 ]

4 голосов
/ 20 июня 2020

Это будет работать независимо от того, может ли какое-либо из цитируемых полей содержать , (например, если какое-либо из полей с текстом заполнителя "Page Title 1" на самом деле было чем-то вроде "I, Robot - Page 1"):

$ awk '
    BEGIN { FS=OFS="," }
    NR==1 { print; next }
    { num=$NF; sub(/,[^,]*$/,""); sum[$0]+=num }
    END { for (key in sum) print key, sum[key] }
' file
url,title,tag,version,guide,views
"https://website.com/2-2/section/product/page-title","Page Title 2",tag-2,"2-2","guide-2",5
"https://website.com/4-4/section/product/page-title","Page Title 4",tag-4,"4-4","guide-4",7
"https://website.com/1-1/section/product/page-title","Page Title 1",tag-1,"1-1","guide-1",115
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",60
2 голосов
/ 20 июня 2020

другой awk

$ awk -F, -v OFS=, 'NR==1 {print; next} 
                          {v=$NF; NF--; a[$0]+=v} 
                    END   {for(k in a) print k,a[k] | "sort"}' file

url,title,tag,version,guide,views
"https://website.com/1-1/section/product/page-title","Page Title 1",tag-1,"1-1","guide-1",115
"https://website.com/2-2/section/product/page-title","Page Title 2",tag-2,"2-2","guide-2",5
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",60
"https://website.com/4-4/section/product/page-title","Page Title 4",tag-4,"4-4","guide-4",7

Пояснение
распечатать строку заголовка; сохранить значение (последнее поле), уменьшить количество полей, чтобы оставшаяся часть записи стала ключом ($ 0), добавить значение в аккумулятор с ключом (будет суммироваться эквивалентные значения ключей). В конце выведите ключ и значение и выполните сортировку.

2 голосов
/ 20 июня 2020

Одностороннее использование данных GNU sh:

$ echo "url,title,tag,version,guide,views" && datamash --header-in -st, -g1,2,3,4,5 sum 6 < input.txt
url,title,tag,version,guide,views
"https://website.com/1-1/section/product/page-title","Page Title 1",tag-1,"1-1","guide-1",115
"https://website.com/2-2/section/product/page-title","Page Title 2",tag-2,"2-2","guide-2",5
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",60
"https://website.com/4-4/section/product/page-title","Page Title 4",tag-4,"4-4","guide-4",7

Или с awk:

$ awk -F, 'NR==1 { print; next }
           { groups[$1 "," $2 "," $3 "," $4 "," $5] += $6 }
           END { PROCINFO["sorted_in"] = "@ind_str_asc" # Sorted output when using GNU awk
                 for (g in groups) print g "," groups[g]
           }' input.txt
url,title,tag,version,guide,views
"https://website.com/1-1/section/product/page-title","Page Title 1",tag-1,"1-1","guide-1",115
"https://website.com/2-2/section/product/page-title","Page Title 2",tag-2,"2-2","guide-2",5
"https://website.com/3-3/section/product/page-title","Page Title 3",tag-3,"3-3","guide-3",60
"https://website.com/4-4/section/product/page-title","Page Title 4",tag-4,"4-4","guide-4",7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...