C 프로그래머로서 나는 긴 텍스트 파일 출력에 대해 wc -c
(바이트 계산)과 wc -m
(문자 계산) 결과가 매우 다르다는 사실에 놀랐습니다. 나는 항상 그것이 sizeof(char)
1바이트라고 들었습니다.
qdii@nomada ~/Documents $ wc -c sentences.csv
102990983 sentences.csv
qdii@nomada ~/Documents $ wc -m sentences.csv
89023123 sentences.csv
설명이 있나요?
답변1
C의 유형 char
은 바이트이지만 ASCII 문자에 대해 작동합니다.가변 폭 인코딩UTF-8과 같은 인코딩은 문자당 많은 바이트를 차지합니다. 환경 변수에 의해 설정된 로캘에 따라 멀티바이트 시퀀스를 디코딩하려면 wc
이 함수를 사용합니다 . 로캘이 올바르게 설정되면 모든 경우에 동일한 결과를 얻을 수 있습니다. 예를 들어:mbrtowc(3)
LC_CTYPE
qdii@nomada ~/Documents $ LC_CTYPE="C" wc -m sentences.csv
102990983 sentences.csv
답변2
추측되는 것은
귀하의 로케일은 UTF-8 인코딩을 사용합니다.
파일에 있는 문자의 약 10%는 UTF-8로 인코딩하기 위해 여러 옥텟이 필요합니다.
그건 그렇고, 출처 man wc
:
-c, --bytes
print the byte counts
-m, --chars
print the character counts
답변3
최소한의 예
"라고 불리는 유니코드 문자 "é"를 생각해 보세요.악센트가 있는 라틴 소문자 E", 이는날카로운 악센트많은 유럽 언어에서 사용됩니다.
UTF-8 인코딩은 2바이트 길이의 "0xc3 0xa9"입니다.
이를 염두에 두고 우리는 다음을 봅니다.
printf '\xc3\xa9' | LC_CTYPE=en_US.UTF-8 wc -c
printf '\xc3\xa9' | LC_CTYPE=en_US.UTF-8 wc -m
printf '\xc3\xa9' | LC_CTYPE=C wc -c
printf '\xc3\xa9' | LC_CTYPE=C wc -m
산출:
2
1
2
2
그래서 우리는 설명대로 이해합니다https://unix.stackexchange.com/a/51948/32558올바른 UTF-8 수를 얻으려면 wc -m
및 가 필요합니다 LC_CTYPE=en_US.UTF-8
.
내 시스템에서 입력 방법을 사용하여 텍스트 é를 입력하면 결과는 동일합니다.
printf 'é' | LC_CTYPE=en_US.UTF-8 wc -c
우분투 21.04에서 테스트되었습니다.