~からこれ議論する:
私は(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を使用するロケールではシーケンスがé
。é
矇
とにかく、Unicodeコードポイントとはほとんど関係ありません。また、端末や他のディスプレイデバイスに表示されるときに文字クラスターの数や文字列の幅を計算することとは異なります。
存在する:
var="e\xcc\x81"
$var
e
、、、、、、、、\
および9x
バイトと9文字をc
含みます。c
\
x
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 でない場合、動作はシェルによって異なります。また、シェルに従ってUnicodeコードポイントを文字に拡張するときにコードを解析するときに適用されるロケールを考慮するのか、コードを実行するときに適用されるロケールを考慮するのかを考慮します。その地域の真のマップにキャラクターが存在しない場合でも、動作の変化を確認できます。
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、別名Unicode)で定義されている文字セット変換形式であるUTF-8などの文字セット標準文字セットを使用します。 GNUシステムなどの一部のシステムでは、wchar_t
ロケールに関係なく、Unicodeコードポイントを実際に値として使用します。