AWK, Сумма категории

AWK, Сумма категории

У меня есть куча CSV-файлов с похожим содержанием. Значения обычно разделены запятыми и выглядят так.

product_a,  domestic,   500
product_a,  abroad,     15
product_b,  domestic,   313
product_b,  abroad,     35
product_c,  domestic,   411
product_c,  abroad,     84
product_d,  domestic,   25
product_d,  abroad,     2
...

То, чего я пытаюсь добиться с помощью AWK (потому что я считаю, что SED не является подходящим инструментом для таких операций, но я относительно новый пользователь Linux...) — это сумма каждого произведения (столбец 1), вставленная как столбец номер 2. Я могу сделать что-то вроде этого

awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename

чтобы получить эти значения (суммы)

product_a,  515
product_b,  348
product_c,  495
product_d,  27
...

но я все еще не имею ни малейшего представления, как вставить их в качестве второго столбца в исходный файл, в такой форме:

product_a,  515, domestic,  500
product_a,  515, abroad,    15
product_b,  348, domestic,  313
product_b,  348, abroad,    35
product_c,  495, domestic,  411
product_c,  495, abroad,    84
product_d,  27,  domestic,  25
product_d,  27,  abroad,    2
...

В последнее время я немного использую sed и awk, но мои попытки обычно приводят к ошибке (например, попытка использовать скалярное значение как массив).

Порядок строк меня не волнует, но я предполагаю, что смогу использовать ответ в качестве команды пакетного файла.

$ for f in *.csv; do
  That Shiny Enigmatic Command > tmp && mv tmp $f
  done

РЕДАКТИРОВАТЬ
Спасибо @KM. Я достиг того места, где я могу делать то, что хочу, за 3 шага.

1 шаг:

$ for f in *.csv; do 
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' $f | sort > sum$f
done

2-й шаг:

$ for f in [^sum]*.csv; do 
join -t ',' $f sum$f | awk -F, '{print $1"," $4"," $2"," $3}' > tmp && mv tmp $f; 
done

В конечном итоге просто rm sum*.*. Есть ли способ выполнить это как одну команду из терминала? Или вне его?

решение1

Сохраните сумму в файле с именем sum, отсортированном

awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename | sort > sum

cat sum 
product_a, 515
product_b, 348
product_c, 495
product_d, 27

Объедините два файла, первый столбец первого файла с первым столбцом второго (представьте себе «ключи»); передайте их по конвейеру awkи выведите переупорядоченные столбцы, используя ,в качестве разделителя полей ( -F)икак разделитель выходных полей ( -OFS)

join -t ','  -1 1 -2 1 filename sum | awk -F, -OFS=, {'print $1,$4,$2,$3}'

product_a,  515,  domestic,  500
product_a,  515,  abroad,    15
product_b,  348,  domestic,  313
product_b,  348,  abroad,    35
product_c,  495,  domestic,  411
product_c,  495,  abroad,    84
product_d,  27,   domestic,  25
product_d,  27,   abroad,    2

Связанный контент