필요한 여러 열을 합산하는 함수를 만드는 방법

필요한 여러 열을 합산하는 함수를 만드는 방법

여러 열을 합산하려는 시나리오가 있습니다.

파일의 데이터는 다음과 같습니다.

ID|NAME|SAL|COST|PER|TAG

1|A|10|10|20|10|

1|B|10|15|20|10|

1|C|10|17|25|80|

1|D|115|110|20|100|

1|E|10|10|10|10|

COLUMN - SAL 태그의 총 비용을 원합니다 |

간단한 명령어로 하나 만들었는데 함수를 만들어서 어떻게 하는지

awk '{FS="|"}{s+=$3}END{print s}' file.txt

함수는 열 이름을 전달할 때 해당 열의 합계를 계산하도록 매개변수화되어야 합니다.

합계 열은 다를 수 있습니다. 두 개의 열 합계만 필요한 경우 두 개의 열 이름을 가져와 해당 합계를 처리해야 하는 것과 같은 요구 사항이 될 수 있습니다.

답변1

awk입력 문자열에서 공백을 사용 하고 잃습니다.

myv='SAL|COST|PER|TAG'
awk -v ar="$myv" '
  BEGIN{FS="|"; getline; for (i=1;i<=NF;i++) {if ($i ~ ar) head[i]=0;title[i]=$i}}
  NF>1{for (h in head) head[h]+=$h}
  END{for (h in head) print title[h]":\t"head[h]}
' file

이는 정규식 일치가 고유하다고 가정합니다. 그렇지 않다면...

myv='SAL|COST|PER|TAG'
awk -v ar="$myv" '
  BEGIN{FS="|"; getline; for (i=1;i<=NF;i++) head[$i]=i; split(ar,titles,"|")}
  NF>1{for (i=1; i<=NF; i++) val[i]+=$i}
  END{for (t in titles) print titles[t]":\t"val[head[titles[t]]]}
' file

산출

SAL:    155
COST:   162
PER:    95
TAG:    210

답변2

최신 버전을 사용하세요.밀러

$ mlr --csvlite --allow-ragged-csv-input --fs '|' stats1 -a sum -f SAL file.txt
SAL_sum
155

(입력하신 내용이 최신 버전이므로 최신 버전만 필요합니다.떨어진즉, 헤더에 해당 이름이 없는 빈 열이 뒤에 있습니다. 쉼표로 구분된 목록으로 이름을 옵션에 전달하여 Miller에서 여러 열을 쉽게 합산할 수 있습니다 -f.

... stats1 -a sum -f SAL,COST,PER,TAG ...

비슷하다GNU 데이터 혼합

$ datamash -Ht '|' sum SAL,COST,PER,TAG < file.txt
sum(SAL)|sum(COST)|sum(PER)|sum(TAG)
155|162|95|210

답변3

~에서 영감을 얻다https://stackoverflow.com/a/32616101:

$ col=SAL
$ colnum=$(awk -v RS='|' '/'$col'/{ print NR; exit}' testfile)
$ awk '{FS="|"}{s+='$colnum'}END{print s}' testfile 
18

여기서의 비결은 인용입니다. 변수는 작은따옴표 밖에 있습니다.

이는 스크립트로 쉽게 캡슐화됩니다 sumcols.sh.

#!/bin/bash
FILE="$1"
COLUMNS="${@:2}"
for col in $COLUMNS; do
  colnum=$(awk -v RS='|' '/'$col'/{ print NR; exit}' $FILE)
  awk '{FS="|"}{s+='$colnum'}END{print "'$col' ", s}' $FILE
done | column -t

처리할 파일을 첫 번째 위치 인수로 호출하고 그 뒤에 처리할 열을 호출합니다. 예를 들어:

$ ./sumcols.sh testfile SAL COST
SAL   18
COST  24

관련 정보