wc -m과 wc -c는 왜 다른가요?

wc -m과 wc -c는 왜 다른가요?

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

추측되는 것은

  1. 귀하의 로케일은 UTF-8 인코딩을 사용합니다.

  2. 파일에 있는 문자의 약 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에서 테스트되었습니다.

관련 정보