AWK: 누락된 행을 추가하고 csv 파일에서 특정 열을 "0"으로 설정

AWK: 누락된 행을 추가하고 csv 파일에서 특정 열을 "0"으로 설정

(참고: 자세한 질문은 "스팸으로 보입니다."로 차단되어 질문이 크게 단축되었습니다.)

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 시스템의 모든 쉘에서 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

-위의 내용은 예를 들어 "city" 값에 가 포함된 경우 Washington-on-the-Brazos에도 작동합니다 . 왜냐하면 값 -에 이를 포함하지 않고 대신 END 부분을 호출하여 날짜를 연도와 월로 분리했기 때문입니다.FSsplit()

관련 정보