gawk가 데이터를 입력할 때 "0123"을 십진수로 처리하는 이유는 무엇입니까?

gawk가 데이터를 입력할 때 "0123"을 십진수로 처리하는 이유는 무엇입니까?

에 따르면 $ man gawkstrtonum()함수는 문자열을 숫자로 변환할 수 있습니다.

strtonum(str) str을 확인하고 해당 값을 반환합니다. str이 앞에 0으로 시작하면 8진수로 처리됩니다. str이 선행 0x 또는 0X로 시작하는 경우 16진수로 처리됩니다. 그렇지 않으면 10진수로 간주됩니다.

문자열이 로 시작하면 0숫자는 8진수로 간주되고, 로 시작하면 0x16진수로 간주됩니다.

함수에 대한 이해를 확인하기 위해 다음 명령을 실행했습니다.

$ awk 'END { print strtonum("0123") }' <<<''
83

$ awk 'END { print strtonum("0x123") }' <<<''
291

문자열은 "0123"8진수를 포함하는 것으로 올바르게 처리되고 10진수로 변환됩니다 83. 마찬가지로 문자열은 "0x123"16진수를 포함하는 것으로 올바르게 처리되며 10진수로 변환됩니다 291.

이제 동일한 명령을 실행하지만 숫자 문자열을 프로그램 텍스트에서 입력 데이터로 이동하면 다음과 같은 일이 발생합니다.

$ awk 'END { print strtonum($1) }' <<<'0123'
123

$ awk 'END { print strtonum($1) }' <<<'0x123'
291

두 번째 결과가 이전 명령과 동일하다는 것은 이해하지만 첫 번째 결과는 이해되지 않습니다. gawk가 8진수를 특징으로 하는 선행 문자로 시작 0123하더라도 이제 이를 10진수로 처리하는 이유는 무엇입니까 ?0

나는 이것이 뭔가 관련이 있다고 의심한다.문자열 속성, 어떤 이유로 1 gawk는 이 속성을 제공 0123하지만 다음을 제공하지 않기 때문입니다 0x123.

$ awk 'END { print typeof($1) }' <<<'0123'
strnum

$ awk 'END { print typeof($1) }' <<<'0x123'
string

1은 다음으로 인해 발생할 수 있습니다.다양성awk 구현 사이:

명확히 하기 위해 몇 가지 소스의 문자열만 있습니다(여기서는 POSIX 사양 인용): [...] 해당 값이 숫자인 경우(선행 및 후행 공백이 허용됨, 16진수와 8진수를 지원하는 구현에는 차이가 있습니다., inf, 남쪽...).


나는 gawk 버전을 사용하고 4.2.62있으며 그 출력은 $ awk -V다음과 같습니다.

GNU Awk 4.2.62, API: 2.0 (GNU MPFR 3.1.4, GNU MP 6.1.0)

답변1

strnum이는 GAWK 버전 4.2의 일반 처리와 관련이 있습니다.

입력값숫자처럼 생겼어strnum값 으로 처리되며 내부적으로 문자열과 숫자 유형을 모두 갖는 것으로 표시됩니다. "0123"은 숫자처럼 보이므로 으로 사용됩니다 strnum. strtonum문자열 및 숫자 입력을 처리하도록 설계되었습니다.먼저 숫자를 찾습니다., 입력 숫자가 발견되면 변환 없이 해당 숫자를 반환합니다.

NODE *
do_strtonum(int nargs)
{
        NODE *tmp;
        AWKNUM d;

        tmp = fixtype(POP_SCALAR());
        if ((tmp->flags & NUMBER) != 0)
                d = (AWKNUM) tmp->numbr;
        else if (get_numbase(tmp->stptr, tmp->stlen, use_lc_numeric) != 10)
                d = nondec2awknum(tmp->stptr, tmp->stlen, NULL);
        else
                d = (AWKNUM) force_number(tmp)->numbr;

        DEREF(tmp);
        return make_number((AWKNUM) d);
}

이렇게 하면 "0123"은 숫자 123이 되어 strtonum바로 반환됩니다.

"0x123"은 (위에 제공된 링크에 정의된 규칙에 따라) 숫자처럼 보이지 않으므로 문자열로 처리되며 예상대로 처리됩니다 strtonum.

숫자는 다음과 같이 정의됩니다.AWK에서:

입력 문자열은 두 부분, 즉 비어 있을 수 있는 초기 공백 문자 시퀀스(다음으로 정의됨)로 나뉩니다.공간()) 및 부동 소수점 상수로 해석되는 대상 시퀀스입니다.

주제 시퀀스의 예상되는 형식은 선택적 '+'또는 '-'기호, 선택적으로 <마침표>를 포함하는 비어 있지 않은 숫자 시퀀스, 선택적 지수 부분이 뒤따르는 것입니다. 지수 부분은 'e'또는 'E', 선택적 기호, 마지막으로 하나 이상의 소수 자릿수로 구성됩니다.

첫 번째 숫자 또는 <마침표>(둘 중 먼저 발생하는 것)로 시작하는 시퀀스는 C 언어에서 부동 상수로 해석됩니다. 지수 부분이나 <마침표>가 모두 나타나지 않으면 마지막 숫자 뒤의 문자는 문자열로 간주됩니다. 대상 시퀀스가 ​​<하이픈-빼기>로 시작하는 경우 변환으로 생성된 값이 무효화됩니다.

관련 정보