Text-Processing

AWK:在 csv 文件中添加缺失的行並將特定列設置為“0”

  • January 27, 2022

(注意:這個問題被大大縮短了,因為詳細的問題被“這看起來像垃圾郵件”阻止了。)

我很難用 awk/gawk 將缺失的行添加到分號分隔的 csv 文件中的一系列數據中。

樣本數據 (csv)

date;city;gender;status;value
2019-10;New York City;women;AL;5
2019-10;New York City;women;SC;2
2019-10;New York City;men;AL;3
2019-10;New York City;men;SC;1
2019-12;New York City;men;AL;5
2019-12;New York City;men;SC;3
2020-01;New York City;women;AL;8
2020-01;New York City;men;SC;2

目標

每一年(從文件中出現的第一年開始(此處為“2019”)到文件中出現的最後一年(此處為“2020”))和月份(從文件中出現的第一個月開始)文件(此處為“10”)並以文件​​中出現的最後一個月結尾(此處為“01”))應該有 4 行。

“2019-10”月的範例數據顯示了我需要的數據的正確出現:

一年中每個月有 4 行,女性 2 行,男性 2 行,每個狀態為 AL 和 SC。

期望的輸出

date;city;gender;status;value
2019-10;New York City;women;AL;5
2019-10;New York City;women;SC;2
2019-10;New York City;men;AL;3
2019-10;New York City;men;SC;1
2019-11;New York City;women;AL;0
2019-11;New York City;women;SC;0
2019-11;New York City;men;AL;0
2019-11;New York City;men;SC;0
2019-12;New York City;women;AL;0
2019-12;New York City;women;SC;0
2019-12;New York City;men;AL;5
2019-12;New York City;men;SC;3
2020-01;New York City;women;AL;8
2020-01;New York City;women;SC;0
2020-01;New York City;men;AL;0
2020-01;New York City;men;SC;2

缺失的行應該得到值 0。原始數據還包括沒有月線的出現(無論是女性還是男性,甚至沒有傳遞線)。

任何幫助是極大的讚賞。

由於這是我在這個平台上的第一篇文章,而且我的母語不是英語,請原諒我犯的任何錯誤。

在每個 Unix 機器上的任何 shell 中使用任何 awk:

$ cat tst.awk
BEGIN {
   FS=OFS=SUBSEP=";"
   split("women" FS "men", genders)
   split("AL" FS "SC", statuses)
}
NR == 1 {
   print
   next
}
{
   vals[$1,$2,$3,$4] = $5
   if ( NR == 2 ) {
       begDate = $1
       city = $2
   }
   endDate = $1
}
END {
   split(begDate,begYm,/-/)
   split(endDate,endYm,/-/)
   for ( yr=begYm[1]; yr<=endYm[1]; yr++ ) {
       begMth = ( yr == begYm[1] ? begYm[2] : 1 )
       endMth = ( yr == endYm[1] ? endYm[2] : 12 )
       for ( mth=begMth; mth<=endMth; mth++ ) {
           date = sprintf("%04d-%02d", yr, mth)
           for ( i=1; i in genders; i++ ) {
               for ( j=1; j in statuses; j++ ) {
                   idx = date FS city FS genders[i] FS statuses[j]
                   print idx, vals[idx]+0
               }
           }
       }
   }
}
$ awk -f tst.awk file
date;city;gender;status;value
2019-10;New York City;women;AL;5
2019-10;New York City;women;SC;2
2019-10;New York City;men;AL;3
2019-10;New York City;men;SC;1
2019-11;New York City;women;AL;0
2019-11;New York City;women;SC;0
2019-11;New York City;men;AL;0
2019-11;New York City;men;SC;0
2019-12;New York City;women;AL;0
2019-12;New York City;women;SC;0
2019-12;New York City;men;AL;5
2019-12;New York City;men;SC;3
2020-01;New York City;women;AL;8
2020-01;New York City;women;SC;0
2020-01;New York City;men;AL;0
2020-01;New York City;men;SC;2

請注意,即使您的“城市”值包含 a ,上述內容也會起作用-,例如Washington-on-the-Brazos,因為我不包含-FS值中,而是split()在 END 部分呼叫以將日期分隔為年和月。

引用自:https://unix.stackexchange.com/questions/688226