이 페이지GNU awk 구현 제한에 관해서는 필드 크기 및 리터럴 문자열 크기에 대한 제한이 언급되어 있습니다 MAX_INT
.
그러나 긴 문자열 리터럴을 변수로 선언하고 함수를 사용하여 길이를 찾으려고 하면 length
문자열 길이가 308자를 초과하면 함수가 중단되는 것 같습니다. 아래 예:
BEGIN {
avar=1234... #309 characters
print length(avar) #prints 3 but prints right length when length < 309
}
그러나 다음 명령줄은 1000자까지 작동합니다.
echo 1234... | awk '{print length($1)}' #tested and works for 1000 characters
CentOS 7 시스템을 사용하고 있으며 awk 버전은 4.0.2입니다.
이 차이가 발생하는 이유에 대한 제안 사항이 있습니까?
답변1
수행하려는 작업을 반복하기가 더 쉬울 수 있습니다.
awk 'BEGIN {
avar='"$(printf '%0200d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
} '
이는 0 1
200개의 0으로 구성된 전체 목록이 awk에 의해 단일로 변환됨을 의미합니다 0
. 이는 다음과 같은 의미인 것 같습니다.값0이 200개 있는 정수를 쓰세요.
다른 값을 지정해 보겠습니다(8 뒤에 0이 200개 있음).
➤ awk 'BEGIN {
avar='"$(printf '8%0200d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
} '
799999999999999975786497770008289327579602620364018901185934007602774787484432604273570707237650014944220099327791059265457085874946227877115080328377919022968188728534319854489454506449337030839107584 201
이는 의 부동 소수점 근사치입니다 8e200
. 이는 다음을 통해 쉽게 확인할 수 있습니다.
➤ awk 'BEGIN {
avar='"$(printf '8%0200d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
printf "%15e\n",avar
} '
799999999999999975786497770008289327579602620364018901185934007602774787484432604273570707237650014944220099327791059265457085874946227877115080328377919022968188728534319854489454506449337030839107584 201
8.000000e+200
따라서 코드 할당()에 지정된 숫자는 avar=
숫자 값으로 (올바르게) 처리됩니다. 이중 부동 소수점 숫자는 최대 308까지의 지수만 저장할 수 있습니다(비정규 숫자 제외). 따라서 308비트를 초과하는 값은 부동소수점 숫자로 변환할 수 없습니다.
➤ ➤ awk 'BEGIN {
avar='"$(printf '8%0308d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
printf "%15e\n",avar
} '
inf 3
inf
단, 문자열이므로 avar="..."
큰따옴표( )로 묶어도 문제가 없습니다.
➤ awk 'BEGIN {
avar="'"$(printf '8%0600d' 0)"'" #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
} '
8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 601
데이터가 파이프(또는 파일)에서 오는 경우 데이터는 문자열로 간주되며( data + 0
또는 이와 유사한 숫자로 변환되지 않는 한) 해당 길이는 문자 수입니다.
$ printf '8%02000d0\n' 0 | awk '{print length($1)}'
2002