Har*_*ald 2 character-encoding awk unicode
尝试以下输出|\xc3\x9c| X|
:
echo \'\xc3\x9c X\' | awk \'{printf("|% 2s|% 2s|\\n", $1, $2)}\'\n
Run Code Online (Sandbox Code Playgroud)\n显然awk
计算的是字节长度,而不是 的字符长度\xc3\x9c
,因此计数为 2,并且不需要用空格进行左填充,就像 一样X
。
是否可以awk
在计算模式字符长度%<count>s
printf
而不是字节长度的模式下运行?
\'s也存在同样的bash
printf
问题。我希望答案不一样:“passthrough to libc printf”:-/
我没有使用,但是Ubuntu\xc2\xa022.04 (Jammy Jellyfish) 已经为我安装了gawk
任何版本。我没想到这些天可以安装任何东西:-/gawk
GNU awk(可能还有其他一些 awk 变体):
\n$ echo \'\xc3\x9c X\' | LC_ALL=\'en_US.UTF-8\' awk \'{printf "|% 2s|% 2s|\\n", $1, $2}\'\n| \xc3\x9c| X|\n
Run Code Online (Sandbox Code Playgroud)\nBash 3.0+(可能还有一些其他 shell,可能进行了调整):
\n$ LC_ALL=\'en_US.UTF-8\' a=\'\xc3\x9c\' b=\'X\'\n$ printf \'|%*s%s|%*s%s|\\n\' "$(( 2 - ${#a} ))" \'\' "$a" "$(( 2 - ${#b} ))" \'\' "$b"\n| \xc3\x9c| X|\n
Run Code Online (Sandbox Code Playgroud)\n请注意,bash 版本必须LC_ALL
在正在执行的 shell 中设置${#a}
,而不仅仅是在版本printf
发生的环境中设置awk
,因此如果您不想LC_ALL
在调用 shell 中更改,则需要保存/恢复它, ie o="$LC_ALL"; LC_ALL=\'en_US.UTF-8\' ... "$b"; LC_ALL="$o"
,或者在子 shell 中执行所有操作, ie ( LC_ALL=\'en_US.UTF-8\' ... "$b" )
。
说明:
\n来自GNU awk 文档:
\n\n\nRun Code Online (Sandbox Code Playgroud)\n-b\n--characters-as-bytes\n
使 gawk 将所有输入数据视为单字节字符。此外,所有使用 print 或 printf 写入的输出都被视为单字节字符。
\n通常,gawk 遵循 POSIX 标准并尝试根据当前语言环境处理\n输入数据(请参阅“你所在位置的差异”)。这通常涉及将多字节字符转换为宽字符(内部),并且如果输入数据不包含有效的多字节字符,则可能会导致问题或混乱。这个选项是告诉gawk的简单方法,\xe2\x80\x9c放弃我的\n数据!\xe2\x80\x9d
\n
使用 GNU awk 5.2.2 设置适当的语言环境会将多字节字符视为单个多字节字符:
\n$ echo \'\xc3\x9c X\' | LC_ALL=\'en_US.UTF-8\' awk \'{printf "|% 2s|% 2s|\\n", $1, $2}\'\n| \xc3\x9c| X|\n
Run Code Online (Sandbox Code Playgroud)\n而使用不同的语言环境或使用-b
,会将所有输入视为单字节字符:
$ echo \'\xc3\x9c X\' | LC_ALL=\'C\' awk \'{printf "|% 2s|% 2s|\\n", $1, $2}\'\n|\xc3\x9c| X|\n\n$ echo \'\xc3\x9c X\' | awk -b \'{printf "|% 2s|% 2s|\\n", $1, $2}\'\n|\xc3\x9c| X|\n
Run Code Online (Sandbox Code Playgroud)\n使用时,-b
结果与您的区域设置无关:
$ echo \'\xc3\x9c X\' | LC_ALL=\'en_US.UTF-8\' awk -b \'{printf "|% 2s|% 2s|\\n", $1, $2}\'\n|\xc3\x9c| X|\n\n$ echo \'\xc3\x9c X\' | LC_ALL=\'C\' awk -b \'{printf "|% 2s|% 2s|\\n", $1, $2}\'\n|\xc3\x9c| X|\n
Run Code Online (Sandbox Code Playgroud)\n正如@St\xc3\xa9phaneChazelas在评论中提到的,请参阅Why is printf "shrinking" umlaut? printf
对于shell 中的相关行为,其中@L\xc3\xa9a Gris\ 的答案表明这将获得字符计数,因此格式化的输出在 bash 3.0 及更高版本中是正确的:
$ a=\'\xc3\x9c\' b=\'X\' LC_ALL=\'en_US.UTF-8\' \n$ printf \'|%*s%s|%*s%s|\\n\' "$(( 2 - ${#a} ))" \'\' "$a" "$(( 2 - ${#b} ))" \'\' "$b"\n| \xc3\x9c| X|\n
Run Code Online (Sandbox Code Playgroud)\n该功能也受区域设置的影响:
\n$ LC_ALL=\'C\'\n$ printf "|%*s%s|%*s%s|\\n" "$(( 2 - ${#a} ))" \'\' "$a" "$(( 2 - ${#b} ))" \'\' "$b"\n|\xc3\x9c| X|\n
Run Code Online (Sandbox Code Playgroud)\n有关获取 bash 中字符长度的更多信息,另请参阅length -of-string-in-bash 。
\n 归档时间: |
|
查看次数: |
278 次 |
最近记录: |