在bash中将unicode数组转换为字符串



我有一个unicode点数组,我希望能够转换回字符并将其作为字符串存储在变量中。在下面的例子中,它只是"Hello World!"代码点数组,但我可以有任何unicode数字(最多16位)。

array=( 72 101 108 108 111 32 87 111 114 108 100 33 )

我检查了:

  • 如何在*nix中使用控制台工具将uXXXX unicode转换为UTF-8
  • 如何将字符串中的所有UTF8 Unicode字符转换为使用bash/shell/zsh的相关代码点?

和其他在线资源,但我仍然不知道如何做到这一点。我尝试了如下操作:

temp=
for c in ${array[@]}; do
temp+="U$c"
done
printf %b "$temp"

我还看到bash有一个新功能,允许您执行echo -e 'Uxxxxx'$'Uxxx',但在我的情况下,它不起作用,因为即使我迭代数组并将每个代码点存储在变量i中,单引号会阻止bash在这种情况下扩展它:echo $'U$i',我甚至尝试了echo "$'U$i'"

我完全不知道如何用一种简单的方式用纯bash来做这件事。

让您感到困惑的是,您的数组中充满了编码点的十进制数字,但是U符号采用十六进制数字。例如,数组中的第一个元素是"72"——在十进制中,这是"H"的代码,但在十六进制中,它相当于十进制114,这是" "的代码。

所以要使用U表示法,首先需要将数字转换为十六进制,可以使用printf %x:

for c in "${array[@]}"; do
temp+="\U$(printf %x "$c")"    # Convert dec->hex, add U
done
printf %b "$temp"    # Convert U<codepoint> to actual characters

正如dave_thompson_085在注释中指出的那样,您可以通过将整个数组转换为单个printf:

来进一步简化这一点:
printf %b "$(printf '\U%x' "${array[@]}")"

Shell脚本不是万能的。对于复杂的操作,它们通常依赖于linux安装中常见的其他实用程序。在这种情况下,iconv可以提供帮助。

array=( 72 101 108 108 111 32 87 111 114 108 100 33 )
temp=
for c in ${array[@]}; do temp+=$(printf '\x%x' $c); done
temp=$(echo -ne $temp | iconv -f utf8)
printf %b "$temp"

为什么要调用数组array,然后继续使用string?

tmp=""
arr=( 72 101 108 108 111 32 87 111 114 108 100 33 )
for c in "${arr[@]}"; do tmp+="U$c"; done
printf %b "$tmp"

相关内容

  • 没有找到相关文章

最新更新