첫 번째 행을 건너뛰어 특정 형식으로 열을 인쇄하고 아래에서 일부 산술을 수행하려면 어떻게 해야 합니까? 다음에는 괜찮나요?
입력하다
#filename
4e+06 5e+06 6e+06
5e+06 5e+06 6e+06
암호:
BEGIN { CONVFMT="%0.17f" }
function t(n, s) {
s=index(n,".")
return (s ? substr(n,1,s+2) : n)
}
FR>1 {print t($1-1000),t($2)}
답변1
방금 awk 스크립트의 마지막 줄에 오타를 냈습니다. 주소 FNR
대신 읽어야 합니다.FR
BEGIN { CONVFMT="%0.17f" }
function t(n, s) {
s=index(n,".")
return (s ? substr(n,1,s+2) : n)
}
FNR>1 {print t($1-1000),t($2)}
여기서는 예상대로 작동합니다.
오타로 인해 주소가 FR>1
어떤 데이터 행과도 일치하지 않습니다. FR
는 상수이고 조건은 FR>1
항상 false입니다. 그렇기 때문에 아무런 출력도 얻지 못합니다.
답변2
첫 번째 줄을 건너뛰는 방법에는 여러 가지가 있습니다.
NR>1{ … } # For every record after the first.
BEGIN{ getline } # Only on the start, read the first line
!var{var=1;next} # If var is unset, set it and skip one line.
FNR>1{ … } # For records after the first for every file listed.
이 변수는 NR
"레코드 수"를 나타내며 기본 레코드 구분 기호(개행)가 사용된다고 가정하면 이 또한 행 수입니다. 첫 번째 행(이 경우)에는 번호가 매겨져 있습니다 1
. NR
더 큰 경우 1
중괄호 내부에서 실행되는 내용은 첫 번째 줄 이후에만 실행됩니다.
대신 변수는 FNR
명령줄( )에 나열된 각 파일의 레코드 번호가 0으로 재설정되었음을 나타냅니다 awk 'script' file1 file2 filen …
. 이는 NR>1
모든 새 파일과 정확히 동일하지만 재설정됩니다.
트림 기능
또한 귀하의 의견에 따라 "숫자를 소수점 이하 두 자리까지 자르기"라는 목표를 가진 함수 정의가 있지만 t(n,s)
이를 올바르게 수행하지 않습니다.
함수 정의에 점을 찾는 명령어가 있습니다. 점이 소수 구분 기호라고 가정합니다.
s=index(n,".")
그런 다음 (문자열로) 해당 지점 뒤의 두 문자 필드의 문자열을 자릅니다. 지수가 없는 숫자의 경우 소수가 올바르게 잘렸지만 숫자가 지수를 사용하고 있습니다(예: ) 1.2345678e3
. 물론 소수점 이하 두 자리까지 정확하게 자르는 1.23
것과는 다릅니다 1234.56
.
숫자를 올바르게 자르려면 지수를 고려해야 합니다. 이 int
함수는 정확히 다음을 수행합니다.
function ti(n){ return( int(100*n)/100 ) }
그러나 부동 소수점 숫자에 적용되는 근사치를 더 잘 사용할 수 있습니다.
function tf(n){ return( sprintf( "%.2f",n ) ) }
근사 정도(실제 유형)가 다릅니다. int를 사용하는 함수는 0을 향해 더 작은 정수(양수의 경우)로 반올림됩니다. 와 같은 숫자의 경우 오류는 3.7
어쨌든 반올림됩니다 . 부동 소수점 숫자를 사용하는 함수는 가장 가까운 정수로 반올림됩니다. 최대 오차는 입니다 . 위 수치를 반올림 하면 오차는 입니다 . 그러니까 하나는 하나다3
0.7
0.5
3.7
4
0.3
0을 향해 반올림의 근사값은 다음과 같습니다.가장 가까운 정수로 반올림. 하나의 최대 오류는 0.9
이고 다른 하나의 최대 오류는 입니다 0.5
. 부동 소수점 근사의 유일한 이상한 점은 때로는 0.5
반올림되고 때로는 0.5
반올림된다는 것입니다. 이는 반올림과 반내림의 균형을 맞추기 위한 것입니다.
당연히 0.1, 0.2, 0.3, 0.4는 0으로 내림되어야 합니다.
이로 인해 0.1, 0.2, 0.3 및 0.4의 오류가 발생합니다.
하지만 0.9, 0.8. 0.7과 0.6은 1로 반올림됩니다.
이로 인해 -0.1, -0,2, -0.3, -0.4의 오류가 발생합니다.
이러한 모든 오류(임의 입력의 평균 오류)는 균형을 이룹니다.
그러나 항상 0.5로 반올림하면 0.5의 지속적인 오류가 발생합니다.
균형을 맞추기 위해 한 번 내림하면 다음번에는 내림됩니다.
또는 일반적으로 다음과 같이 작성됩니다.원형 관계(0.5)는 짝수입니다..
printf '%s ' $l; echo; printf '%-3.0f ' $l; echo
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2
0.5
반올림 0
(내림) 및 1.5
반올림 2
(올림) 에 유의하세요 .
정확한
CONVFMT="%.16g"
부동 소수점 숫자를 변환하기 위한 형식으로 사용해야 합니다 .
형식은 f
다음과 같이 유효 숫자를 제거합니다.
$ awk 'BEGIN{var=1.23456789e-8;printf "%.9f\n",var}'
0.000000012
유효 숫자는 2개뿐입니다. 오히려 형식은 다음과 같습니다 g
.
$ awk 'BEGIN{var=1.23456789e-8;printf "%.9f\n",var}'
1.23456789e-08
9개의 유효 숫자(숫자)가 유지됩니다.
파일 이름
이는 여러 파일에 적용되는 awk 명령에 유용합니다. 예를 들면 다음과 같습니다.
$ awk 'FNR>1{print $1}' file1 file2 file3
NR 대신 FNR을 사용하므로 해당 조건이 각 파일에 차례로 적용됩니다.