我指的“printf”是标准问题“程序”(不是内置的):/usr/bin/printf
我正在测试 printf 作为将 Unicode Codepoint Hex-literal 转换为其 Unicoder 字符表示的可行方法,
我看起来不错,看起来完美无瑕..(顺便说一句。内置的 printf 根本无法做到这一点(我认为)......
然后我想在代码谱的最低端测试它,但它因大量错误而失败。所有都在 ASCII 范围内(= 7 位)
最奇怪的是正常打印了3个值;他们是:
- $ \u0024
- @\u0040
- ` \u0060
我想知道这里发生了什么。ASCII 字符集绝对是 Unicode 代码点序列的一部分......
我很困惑,仍然没有一个好的方法来编写这个特殊的转换脚本。欢迎提出建议。
要被同样的错误雪崩所吸引,请将以下代码粘贴到终端中......
# Here is one of the error messages
# /usr/bin/printf: invalid universal character name \u0041
# ...for them all, run the following script
(
for nib1 in {0..9} {A..F}; do
for nib0 in {0..9} {A..F}; do
[[ $nib1 < A ]] && nl="\n" || nl=" "
$(type -P printf) "\u00$nib1$nib0$nl"
done
done
echo
)
三个工作字符是不在C基本字符集中的三个可打印 ASCII 字符。在 C 语言中禁止这些字符的原因是编译器很难:它们需要
\u
在词法分析之前执行插值,我认为这会在一些极端情况下中断,并且无论如何在许多编译器中都是不切实际的(因为基本集合之外的字符只需要在少数地方允许)。在 shell 实用程序中使用相同的禁止字符没有意义。我怀疑这是一个错误,并且
$
,@
也不`
应该工作。不支持它们的原因再次是为了更容易解析字符串。例如,如果您想确定要放入数据库查询的字符串中没有特殊字符,您可以检查该字符串是否不包含'
,而不必担心它是否包含\u002a
。考虑使用GNU coreutils 手册中建议的重新编码,或者(在实践中更便携)Perl 或 python。
printf 命令有理由不接受此范围内的字符。如果您查看 printf 的源代码,您将看到以下注释:
您也许可以在没有该检查的情况下重新编译,但对我来说这看起来很刻意。尝试使用不带 \u 的命令,例如:
印刷品(手动格式调整)
请注意,一些“字符”控制代码“有效”,即。HT、VT、LF。等等