UTF-8
是Unicode 的可变长度编码。它被设计为ASCII的超集。有关编码的详细信息,请参见Wikipedia。\x00 \x01 \xF6 \x15
将是UCS-4BE
或UTF-32BE
编码。
为了从Unicode代码点转换为UTF-8编码,假设语言环境的超级用户名是UTF-8(请参阅参考资料的输出locale charmap
),它只是:
$ printf '\U1F615\n'
😕
$ echo -e '\U1F615'
😕
$ confused_face=$'\U1F615'
后者将在POSIX标准的下一版本中。
据我所知,这句法是在2000年由独立的GNU介绍printf
实用程序(而不是在printf
GNU的外壳的实用程序),提请echo
/ printf
/ $'...'
内建首先通过zsh
在2003年,ksh93的2004年,庆典在2010年(虽然不能正常工作有直到2014年),但显然受到其他语言的启发。
ksh93
也支持printf '\x1f615\n'
和printf '\u{1f615}\n'
。
$'\uXXXX'
并$'\UXXXXXXXX'
通过支持zsh
,bash
,ksh93
,mksh
和FreeBSD sh
,GNU printf
,GNU echo
。
尽管POSIX会允许更少的数字,但某些版本要求所有数字(与\U0001F615
相对应\U1F615
),但在以后的版本中可能会更改。无论如何,您都需要所有数字(如果\UXXXXXXXX
要在后面加上的十六进制数字)\U0001F615FOX
,就像\U1F615FOX
以前那样$'\U001F615F'OX
。
在解析字符串时或在扩展字符串时,有些扩展为当前语言环境编码中的字符,有些仅在UTF-8中而不考虑语言环境。如果该字符在当前语言环境的编码中不可用,则行为在外壳之间会有所不同。
因此,为了获得最佳的可移植性,最好仅在UTF-8语言环境中使用它并使用所有数字,然后在$'...'
以下位置使用它:
printf '%s\n' $'\U0001F615'
注意:
LC_ALL=C.UTF-8; printf '%s\n' $'\U0001F615'
要么:
{
LC_ALL=C.UTF-8
printf '%s\n' $'\U0001F615'
}
不会与所有的炮弹(包括工作bash
),因为$'\U0001F615'
在解析之前LC_ALL
被分配。(还请注意,不能保证系统具有名为的语言环境C.UTF-8
)
您需要:
LC_ALL=C.UTF-8; eval "confused_face=$'\U0001F615'"
要么:
LC_ALL=C.UTF-8
printf '%s\n' $'\U0001F615'
(不在复合命令或功能内)。
对于反向,从UTF-8编码为Unicode代码点得到,见该另一问题或那一个。
$ unicode 😕
U+1F615 CONFUSED FACE
UTF-8: f0 9f 98 95 UTF-16BE: d83dde15 Decimal: 😕
😕
Category: So (Symbol, Other)
Bidi: ON (Other Neutrals)
$ perl -CA -le 'printf "%x\n", ord shift' 😕
1f615
\U1F615
后面跟随另一个有效的十六进制数字,则将其视为转义序列的一部分。要使其工作,无论其紧随其后的是什么,它都必须有足够的前导零以精确到八位数字长:\U0001F615