awk 명령을 사용하여 다음 레코드를 집계하는 방법

awk 명령을 사용하여 다음 레코드를 집계하는 방법

입력으로 다음 레코드가 있습니다.abc.dat

201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1

이제 필드 1~10의 그룹화를 기반으로 필드 11, 12, 13을 집계해야 합니다.

따라서 내 출력은 다음과 같아야 합니다.

201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~192~0~16

다음을 시도했습니다.

awk 'BEGIN{FS=OFS="~";}{a[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$11;b[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$12;c[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$13} END {for (i in a) print i,a[i],b[i],c[i]}' abc.dat > abc1.dat

그러나 출력은 다음과 같습니다.

201901^Y230615^Y41302^Yblank^Yblank^Y05^YU099164^YARS^Yblank^Y030~192~0~16

추가 ^Y기호가 제공됩니다.

답변1

정말 이상해요. 배열 키 내부에서 사용하면 awk질식하는 것처럼 보입니다 . ~어쩌면 일치 연산자 때문일 수도 있지만 ~확실하지 않습니다. 그럼에도 불구하고 이는 원하는 대로 작동합니다.

$ awk 'BEGIN{FS=OFS="~";}
       {
        key=$1"~"$2"~"$3"~"$4"~"$5"~"$6"~"$7"~"$8"~"$9"~"$10;
        a[key]+=$11;
        b[key]+=$12;
        c[key]+=$13
       } 
       END {
        for (i in a){
         print i,a[i],b[i],c[i]
       }
    }' file 
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~192~0~16

답변2

awk해결책이 아닌 것이 괜찮다 면 csvsql시도해 볼 수 있습니다.csvkit, 이는 다음을 위한 완벽한 도구가 될 것입니다:

csvsql -H -d '~' --query '
    select a,b,c,d,e,f,g,h,i,j,sum(k),sum(l),sum(m)
    from file
    group by a,b,c,d,e,f,g,h,i,j
' file

산출:

201901,230615,41302,blank,blank,5,U099164,ARS,blank,30,192,0,16

출력을 ~-로 구분 해야 하는 경우 | csvformat -D '~'.

답변3

awk와 sed의 조합을 사용하여 다음과 같은 방법으로 수행했습니다.

awk -F "~" 'BEGIN{sum=0;add=0;wo=0}{sum=sum+$NF}{add=add+$(NF-2)}{wo=wo+$(NF-1)}END{$NF=" ";$(NF-1)=" ";$(NF-2)=" ";print $0,add,wo,sum}' filename | sed -r "s/\s+/ /g"| sed "s/ /~/g"

산출

awk -F "~" 'BEGIN{sum=0;add=0;wo=0}{sum=sum+$NF}{add=add+$(NF-2)}{wo=wo+$(NF-1)}END{$NF=" ";$(NF-1)=" ";$(NF-2)=" ";print $0,add,wo,sum}' p.txt | sed -r "s/\s+/ /g"| sed "s/ /~/g"

201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~192~0~16

답변4

이렇게 하면 a[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$11
awk는 이것을 키로 사용합니다. $1 SUBSEP $2 SUBSEP $3 SUBSEP $4 SUBSEP $5 SUBSEP $6 SUBSEP $7 SUBSEP $8 SUBSEP $9 SUBSEP $10
여기서 개별 요소는 변수의 내용으로 연결됩니다 SUBSEP. 기본적으로 이 값은 "\034"입니다.

바라보다https://www.gnu.org/software/gawk/manual/html_node/MultiDimension.html

이를 수용하려면 다음을 사용하십시오.BEGIN{FS = OFS = SUBSEP = "~"}

관련 정보