(注意:这个问题被大大缩短了,因为详细的问题被“这看起来像垃圾邮件”阻止了。)
我很难使用 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。原始数据还包括没有月份行的事件(无论是女性还是男性,甚至没有提供任何行)。
任何帮助是极大的赞赏。
由于这是我在这个平台上的第一篇文章,而且我的母语不是英语,请原谅我犯的任何错误。
答案1
在每个 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
请注意,即使您的“城市”值包含-
, 例如Washington-on-the-Brazos
,上述内容也将起作用,因为我没有包含-
在FS
值中,而是调用split()
END 部分将日期分隔为年和月。