如何打印 UTF-8 符号

如何打印 UTF-8 符号

如何使用 bash 命令在终端上打印 UTF-8 符号。

这有效

echo -e '\U2586'

但以下是失败的

printf '%s\n' $(tput setaf 118) "\\u2586" $(tput sgr0)

答案1

在bash中,如果你想printf在格式字符串后面的参数中扩展反斜杠转义序列,你应该使用%b而不是%s在格式字符串中:

printf '%b\n' "$(tput setaf 118)" "\u2586" "$(tput sgr0)"

既然你有三个论点,也许这可能更合适:

printf '%s%b%s\n' "$(tput setaf 118)" "\u2586" "$(tput sgr0)"

作为斯蒂芬·查泽拉斯指出,这将输出当前语言环境字符集中 U+2586 字符的编码。如果是 UTF-8,则结果将是 UTF-8;其他字符集会有所不同。如果字符集无法表示 U+2586,则结果将是字符串“\u2586”(zsh 将失败并出现“字符不在范围内”错误)。

这会在大多数情况下产生您想要的行为:如果可能,它会显示“▆”。如果你真的想要输出字符的 UTF-8 表示形式,在所有情况下,您可以通过覆盖区域设置来强制执行此操作,例如

LC_ALL= LC_CTYPE=en_US.UTF-8 printf '%s%b%s\n' "$(tput setaf 118)" "\u2586" "$(tput sgr0)"

(看LANG=C 和 LC_ALL=C 有什么区别?有关上面使用的变量设置的说明。)

答案2

\uxxxx请注意,对和 的支持\UXXXXXXXX首次添加到printf2000 年独立实用程序的 GNU 实现中,但与其他转义序列一样,它们仅在格式参数或说明%b符的参数中被识别。不用于%s逐字显示字符串。

它们后来被添加到2003 年printf的内置函数zsh中(也适用于echo/print$'...'There),2004 年的 ksh93,2010 年的 bash (4.2) 以及此后可能还添加了一些内置函数。

但这不是标准的。有计划POSIX 指定$'...'ksh93 的引号形式并且它们允许\u/\U序列,但目前的阻塞点之一是如果在解析和/或运行使用这些引号的命令时当前语言环境中的字符集不是 UTF-8,如何处理扩展。

尽管如此,如果您的脚本是在字符集为 UTF-8 的语言环境中启动的,并且此后您没有更改语言环境( 、LC_CTYPELC_ALL变量LANG),则使用$'\uxxxx'可能是获取基于字符的 UTF-8 编码的最可移植的方法在其 Unicode 代码点上。

用于$'\UXXXXXXXX'代码点高于 0xFFFF 的字符。请注意,有些 shell 确实要求 的所有 4 位数字\u和 的所有 8 位数字\U。因此,为了获得最大的可移植性,例如,使用或$'St\u00E9phane'。在任何 shell 中,您都需要 ,因为是十六进制数字,所以会被视为。对于支持的 shell ,您还可以使用或和 混合搭配引号运算符。$'St\U000000E9phane'StéphaneSt\u00E9fanStéfan$'St\ue9fanSt \U0E9F anef$'\ue9'$'St\ue9'$'fan'St$'\ue9'fan

然后您可以将这些扩展传递给任何命令printf或其他命令。

在您的特定情况下,您可以使用zsh'sprint内置函数:

print -P '%F{118}\u2586%f'

其中-P启用提示扩展,无需运行命令即可设置前景色tput。或者:

print -rP '%F{118}'$'\u2586''%f'

where禁用转义序列并使用引号的形式-r按字面传递 U+2586 字符。print$'...'

或者:

arbitrary_text=$'\u2586'' arbitrary text with \backslash and % characters'
print -r -- ${(%):-%F{118}}$arbitrary_text${(%):-%f}

其中print不进行任何扩展,但颜色转义序列由%参数扩展标志生成,并且 U+2586 逐字存储在变量中。打印-r

相关内容