3개의 열(구분 기호는 쉼표)로 구성된 파일이 있습니다. 첫 번째 열에는 ID가 포함되고 두 번째와 세 번째 열에는 합계하려는 값이 포함됩니다. 합계는 출력의 파일에 네 번째 열로 추가되어야 합니다.
그러나 경우에 따라 세 번째 열이 비어 있을 수 있습니다(예: 입력 파일의 두 번째 행). 이 경우 합계와 관련된 열은 비어 있어야 합니다. 그러나 필드가 명시적으로 표시되면 0
합계는 평소와 같이 계산되어야 합니다(예: 입력 파일의 4번째 줄).
- 입력.txt
2309,-0.3,0.2 2311,1.2, 2312,0,-1 2315,2.2,0
- 원하는 출력:
2309,-0.3,0.2,-0.1 2311,1.2,, 2312,0,-1,-1 2315,2.2,0,2.2
이전에 비슷한 토론을 본 적이 있지만 두 번째 열과 세 번째 열 사이에서 합계를 계산해야 함을 지정하는 방법과 세 번째 열이 비어 있는 행의 합계를 건너뛰는 방법을 모르겠습니다. 아래 스크립트는 동일한 행(또한 ID??)에 포함된 모든 값을 합산하도록 되어 있는데, 어떻게든 수정할 수 있나요? 아니면 다른 더 빠른 방법을 제안해 주실 수 있나요?
NF++; $NF=sum
awk -v OFS=, -F, 'NR>1{sum=0; for(i=1; i<=NF; i++) sum += $i; NF++; $NF=sum } 1'
답변1
$ awk 'BEGIN{FS=OFS=","} {print $0, ($3=="" ? "" : $2+$3)}' input.txt
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
답변2
$ cat dst
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
$ cat awkscript
#!/bin/sh
awk -F, '
{
if ($3 == "") $0 = $0 ","
else $0 = $0 "," $2+$3
print $0
}
' $1 >$2
$ ./awkscript src dst
$ cat dst
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
답변3
이는 다음 절차를 사용하여 awk
가능합니다 .
awk 'BEGIN{FS=OFS=","} {sum=0; for (i=2;i<=NF;i++) {if ($i=="") {sum=""; break}; sum+=$i}; $(NF+1)=sum}1' input.txt
이것은 것이다
- 입력 및 출력 필드 구분 기호(
FS
및OFS
)를 다음으로 설정합니다.,
- 각 행에 대해
sum
변수를 재설정0
하고 필드 2로 시작하는 모든 필드를 합산합니다. 그러나 필드가 명시적으로 비어 있으면($i==""
) 합계 루프에서 벗어나sum
빈 문자열 로 설정됩니다. sum
그런 다음 새 추가 필드를 (실제 합계 또는 빈 문자열) 값으로 설정합니다 .- 마지막으로 모든 수정 사항을 포함하여 현재 줄을 인쇄합니다. 이는
1
규칙 블록 외부에서 "방황"하는 것처럼 보입니다.awk
규칙 블록 외부에 "true"로 평가되는 부울 조건이 있는 경우 현재 행이 인쇄됩니다.
입력 예의 경우 출력은 다음과 같습니다.
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
답변4
mlr
대신 Miller( )를 사용하세요 awk
.
$ mlr --csv -N put 'is_not_empty($3) { $4 = $2 + $3 }' then unsparsify file
2309,-0.3,0.2,-0.100000
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.200000
이렇게 하면 null이 아닌 세 번째 필드가 있는 모든 레코드에 네 번째 필드가 생성됩니다. unsparsify
그러면 이 작업은 이전 단계에서 필드가 생성되지 않은 모든 레코드에 누락된 네 번째 필드를 생성합니다.