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 列)的總和,作為一列插入nr 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

第二步:

$ 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

相關內容