저는 bash를 사용하여 CSV 파일에서 필드를 찾고, 그룹화하고, 합계하는 스크립트를 만들고 있습니다. 각 행에는 쉼표로 구분된 필드가 있으며 각각 유사한 규칙을 따릅니다. 쉼표로 구분된 각 필드에는 숫자 값, 등호(=), 영숫자 값이 차례로 표시됩니다. "(숫자)="는 한 줄에 나타날 수도 있고 그렇지 않을 수도 있으며, 그럴 경우 필드 위치가 다를 수 있지만 한 줄에 한 번만 나타납니다. 또한 등호 뒤의 값 길이도 달라집니다.
내 목표의 예가 최고입니다. CSV 파일:
35=D,11=ABCD1,1=ABC,55=XYZ,38=100,40=P,18=M,54=1,59=0,10=111
35=D,11=ABCD2,1=ABC,55=XYZ,40=P,18=M,38=200,54=1,44=10.00,59=0,10=133
35=D,11=ABCD3,1=ABC,55=XYZ,40=P,18=M B,54=1,38=300,44=10.00,59=0,110=200,10=113
35=D,11=ABCD4,1=ABC,55=XYZ,38=400,40=P,18=M B F,54=1,44=10.00,59=0,110=300,10=144
35=D,11=ABCD5,1=ABC,55=ZYX,38=300,40=2,54=1,44=10.00,59=3,10=132
35=D,11=ABCD6,1=ABC,55=ZYX,38=100,40=1,18=C,54=2,59=3,10=131
"38="로 시작하는 모든 필드를 식별한 다음 "=" 뒤의 모든 숫자 값을 합하고 각 "55="로 그룹화하는 스크립트를 원합니다. 각 줄에는 "38=" 및 "55="가 있습니다.
위 파일을 사용한 출력은 다음과 같습니다(정렬은 선택 사항).
55=XYZ 38=1000
55=ZYX 38=400
답변1
밀러를 사용하여http://johnkerl.org/miller/doc, 지금부터input.csv
35=D,11=ABCD1,1=ABC,55=XYZ,38=100,40=P,18=M,54=1,59=0,10=111 35=D,11=ABCD2,1=ABC,55=XYZ,40=P,18=M,38=200,54=1,44=10.00,59=0,10=133 35=D,11=ABCD3,1=ABC,55=XYZ,40=P,18=M B,54=1,38=300,44=10.00,59=0,110=200,10=113 35=D,11=ABCD4,1=ABC,55=XYZ,38=400,40=P,18=M B F,54=1,44=10.00,59=0,110=300,10=144 35=D,11=ABCD5,1=ABC,55=ZYX,38=300,40=2,54=1,44=10.00,59=3,10=132 35=D,11=ABCD6,1=ABC,55=ZYX,38=100,40=1,18=C,54=2,59=3,10=131
그리고 달리는 중
mlr --ofs " " unsparsify then stats1 -a sum -f 38 -g 55 then rename 38_sum,38 input.csv
당신은 할 것
55=XYZ 38=1000 55=ZYX 38=400
답변2
Steeldriver가 나를 좀 이겼지만 난 알아냈어
perl -F'[=,]' -lane '
%row = @F;
$sum{$row{55}} += $row{38};
}{
print "$_ = $sum{$_}" for keys %sum
' file.csv
XYZ = 1000
ZYX = 400
답변3
여기에 해결책이 있습니다 awk
.
awk -F, '{for(a=1;a++<=NF;){
if($a~/^55=/){l=$a}
if($a~/^38=/){b[l]+=substr($a,4)}
}}END{for(x in b){print x,"38="b[x]}}' inp
for(a=1;a++<=NF;){
- 쉼표로 구분된 각 필드를 반복합니다.if($a~/^55=/){l=$a}
- 다음으로 시작하는 필드를 찾으면55=
이를 변수에 저장합니다.l
if($a~/^38=/){b[l]+=substr($a,4)}
- 다음으로 시작하는 필드를 찾으면 변수를 키로 사용하여38=
다음 값을 가져와=
배열에 누적합니다 .b
l
}}END{for(x in b){print x,"38="b[x]}}
- 배열의 내용만 인쇄
답변4
어때요?
awk -F, '
{for (i=1; i<=NF; i++) {split ($i, T, "=")
if (T[1] == 55) IX = T[2]
if (T[1] == 38) NM = T[2]
}
SUM[IX] += NM
}
END {for (s in SUM) print "55=" s, "38=" SUM[s]
}
' file
55=ZYX 38=400
55=XYZ 38=1000
모든 필드를 반복하여 관련 필드를 찾고, T
배열로 분할하고, 55
찾은 경우 인덱스를 추출하고, 38
찾은 경우 합계를 추출합니다. 루프가 끝나면 합산이 수행됩니다. END
섹션 에는 모든 요약 값과 해당 색인이 표시됩니다.