~에서이것논의하다:
내가 (zsh 5.8, bash 5.1.0)
var="ASCII"
echo "${var} has the length ${#var}, and is $(printf "%s" "$var"| wc -c) bytes long"
대답은 간단합니다. 5자이고 5바이트를 차지합니다.
이제 var=Müller
출력은
Müller has the length 6, and is 7 bytes long
이는 ${#}
연산자가 바이트가 아닌 코드 포인트를 계산한다는 것을 나타냅니다. 이건 좀 불분명해요POSIX에서는, 그들은 "문자"를 계산한다고 말합니다. char
일반적으로 POSIX C의 문자가 옥텟이 아닌 경우 이는 더 명확합니다.
어쨌든: 나쁘지 않아요! 다행히 나는 그것을 보았다 LANG==en_US.utf8
.
지금,
var='
답변1
POSIX 호환 셸(Bourne 셸이 아님, 기능은 Korn 셸에서 제공됨)에서 계산 ${#var}
과 같습니다 .wc -m
수치¹ in이고 $var
에 저장된 바이트 시퀀스를 $var
현재 로케일의 문자로 디코딩할 수 없는 경우 동작은 지정되지 않습니다.
현재 로캘(해당 범주)에 따라 LC_CTYPE
바이트를 문자로 디코딩합니다 . 문자 인코딩으로 UTF-8을 사용하는 로케일에서는 0xc3 0xa9 시퀀스가 문자로 디코딩되고, ISO8859-1을 사용하는 로케일에서는 시퀀스가 é
.é
矇
어쨌든 유니코드 코드 포인트와는 거의 관련이 없습니다. 또한 터미널이나 다른 디스플레이 장치에 표시될 때 문자소 클러스터의 수나 문자열 너비를 계산하는 것과도 다릅니다.
존재하다:
var="e\xcc\x81"
$var
e
, \
, x
, c
, c
, \
, x
및 9바이트와 9개의 문자를 포함 8
합니다 1
.
일부 printf
(format 매개변수 또는 %b
format 지시문의 매개변수) 및 echo
구현은 0xcc 바이트로 확장되지만 \xcc
전부는 아닙니다. POSIX에서 \x
이러한 논쟁은 지정되지 않은 동작을 초래합니다. ( 형식 매개변수 및 / 에서 \351
0xe9 바이트로 확장 됩니다).printf
\0351
echo
%b
//(요즘에는 점점 더 많은 쉘)에 , , 바이트를 $var
포함시키 려면 다음과 같이 하십시오.0x65
0xcc
0x81
ksh93
zsh
bash
var=$'e\xcc\x81'
아니면 언제든지 다음과 같이 할 수 있습니다.
var=$(printf 'e\314\201')
locale charmap
그러면 출력 로케일에는 3바이트( 와 같이 ), 2개의 문자( 또는 와 같이 ), 1개의 자소 클러스터( GNU 에서와 같이 )가 UTF-8
포함 되며 일반적으로 너비가 1( 표시된 GNU 에서와 같이 )로 표시됩니다.$var
wc -c
wc -m
${#var}
grep -Po '\X'
wc -L
쉘이 호출되고 코드가 구문 분석되고 실행될 때 로케일이 문자 세트로 UTF-8을 갖는 경우 여러 쉘에서 다음을 수행할 수도 있습니다.
var=$'e\u0301'
및 U+0301(급 악센트 결합)을 포함하는 문자에 대한 $var
UTF-8 인코딩입니다 .e
로케일의 문자 세트가 UTF-8이 아닌 경우 동작은 쉘마다 다릅니다. 또한, 셸에 따라 유니코드 코드 포인트를 문자로 확장할 때 코드를 구문 분석할 때 적용되는 로캘을 고려하는지 아니면 코드를 실행할 때 적용되는 로캘을 고려하는지를 고려합니다. 해당 지역의 참 맵에 캐릭터가 존재하지 않는 경우에도 동작의 변화를 확인할 수 있습니다.
Bourne 쉘에서 문자열의 문자 길이를 얻으려면 다음과 같은 다른 유틸리티를 사용해야 합니다.
length=`expr "x$var" : '.*' - 1` || :
또는:
length=`printf %s "$var" | wc -m`
그러나 여전히 Bourne 쉘이 있는 오래된 시스템을 발견하면 해당 시스템이 명령을 wc
지원하지 않거나 -m
포함하지 않을 가능성이 있습니다.printf
1 POSIX 자체는 바이트 시퀀스와 문자 시퀀스 간의 매핑을 지정하지 않으며 POSIX 로케일에서도 일부 API만 매핑을 정의 및 검색하거나 바이트 시퀀스를 문자 시퀀스로 변환하는 데 사용됩니다( wchar_t
). 시스템은 일반적으로 다른 ISO 표준(ISO/IEC 10646, 일명 유니코드)에서 정의한 문자 세트 변환 형식인 UTF-8과 같은 문자 세트 표준 문자 세트를 사용합니다. GNU 시스템과 같은 일부 시스템은 실제로 wchar_t
로케일에 관계없이 유니코드 코드 포인트를 값으로 사용합니다.