다음 명령을 사용하여 파일 A 이름의 표준 편차를 얻습니다.
1 2 3 평균 23.3107 20.0372 21.7236 21.6905
awk '{x[NR]=$0 ;} END{a=$4; for (i in x){ss += (x[i]-a)^2} sd = sqrt(ss/n); SD}'
치명적이 됨: 0으로 나누어 보세요.
위 명령을 다음과 같이 수정하세요.
awk '{x[NR]=$0 ;} END{a=$4; for (i in x){if (a == 0) $6 ="N/A" 그렇지 않으면 ss += (x[i]-a )^2} sd = sqrt(ss/n) 인쇄 $5 = sd}'
그런데 오류가 여전히 존재하나요? 고마워요 캐스. 제가 추구하는 바를 이해하시나요?
답변1
"n"은 어디에 있나요?
당신은 쓰기:
sd = sqrt(ss/n)
그런데 코드의 어디에 변수 "n"을 할당했습니까? 표면적으로 awk
"n"은 0입니다.
또한 열 5 a=$5
(세 번째 질문, 이 과제가 이 END
섹션에 있는 이유)는 어디에 있나요? 귀하의 예에는 4개의 열만 포함되어 있습니다.
답변2
이런 걸 하고 싶나요? 이것이 귀하의 스크립트를 이해하기 위해 제가 생각할 수 있는 유일한 방법입니다.
awk -v OFS=$'\t' '
FNR == 1 { $5 = "sdev" ; print }
FNR > 1 { a = $4 # field 4 is 'avg'
n = NF-1 # exclude the 'avg' field from the ss calculations.
for (i=1; i <= n; i++) { ss += ($i - a)^2 }
$5 = sqrt(ss/n)
print
}' inputfile
참고: $i
이 줄은 for
값을 참조하지 i
않고 번호가 매겨진 입력 필드를 참조합니다 . 즉 , , 및 을 i
반복합니다 . (스칼라) 변수에는 일반적으로 접두사가 붙기 때문에 이는 쉘이나 사용자에게 명확하지 않을 수 있습니다 .$1
$2
$3
perl
$
NF
는 한 줄의 필드 수이고 는 FNR
현재 입력 파일의 레코드(줄) 번호입니다. 따라서 이 awk
스크립트는 각각 고유한 헤더 줄이 있는 여러 입력 파일을 지원합니다. 한 번에 하나의 입력 파일만 있는 경우 NR
대신 사용할 수 있습니다 FNR
.
예제 출력:
1 2 3 avg sdev
23.3107 20.0372 21.7236 21.6905 1.33661
행당 필드 수에 관계없이 작동하는 또 다른 버전은 다음과 같습니다. 그것은 가정한다마지막행의 필드에는 해당 행에 있는 모든 이전 필드의 평균이 포함됩니다.
$NF
마지막 필드의 값(예: "avg")을 참조하고 $new
(마지막 필드 + 1)을 참조합니다. 즉, 값을 할당하면 줄 끝에 새 필드가 추가됩니다.
awk -v OFS=$'\t' '
FNR == 1 { new = NF+1 # number of new field to add
$new = "sdev"
print
}
FNR > 1 { a = $NF # last field is 'avg'
n = NF-1 # exclude the 'avg' field from the ss calculations.
for (i=1; i <= n; i++) { ss += ($i - a)^2 }
$new = sqrt(ss/n)
print
}' inputfile
입력 행당 5개의 값에 평균을 더한 출력 예:
1 2 3 4 5 avg sdev
23.3107 20.0372 21.7236 20.5328 21.2016 21.3611 1.13107