使用sed将数字替换为Unicode字符的Bash命令

3

我有一个由printf生成的输出

    011010

现在我想使用管道并使用sed来替换0和1,用unicode字符代替二进制(011010)输出。 我可以复制粘贴字符本身来实现此操作,但我想使用像unicode表中找到的值这样的值代替它们。
    Position: 0x2701
    Decimal: 9985
    Symbol: 

如何使用sed与上述值来生成字符?

sed 不理解 Unicode 字符,它只理解字节,因此您无法将 U+2701 替换为其它字符。您可以替换为 U+2701 的 UTF-8 编码,但就 sed 而言,这只是三个字节 \xE2\x9c\x81。 (当然,除非您的输出被解释为 UTF-8,否则这实际上不会成为字符 U+2701。) - abarnert
我尝试了上面的方法,但由于某些原因它不起作用。如果使用sed s/1/\xE2\x9c\x81/g也不行。 - Bruce Strafford
1个回答

14

使用bash (自 v4.2 起) 或 zsh,简单的解决方案是使用 $'...' 语法,它可以理解C转义字符,包括 \u 转义:

$ echo 011010 | sed $'s/1/\u2701/g'
0✁✁0✁0

如果你使用Gnu sed,你可以在`s//`命令中使用转义序列。不幸的是,Gnu sed不理解`\u`的Unicode转义,但它理解`\x`的十六进制转义。然而,为了让它解码它们,你需要确保它看到反斜杠。然后,你可以在UTF-8中进行翻译,假设你知道与Unicode代码点对应的UTF-8序列:
$ # Quote the argument
$ echo 011010 | sed 's/1/\xE2\x9C\x81/g'
0✁✁0✁0
$ # Or escape the backslashes
$ echo 011010 | sed s/1/\\xE2\\x9C\\x81/g
0✁✁0✁0
$ # This doesn't work because the \ is removed by bash before sed sees it
$ echo 011010 | sed s/1/\xE2\x9C\x81/g
0xE2x9Cx81xE2x9Cx810xE2x9Cx810
$ # So that was the same as: sed s/1/xE2x9Cx81/g

2
有不同的 sed 方言;并非所有方言都理解 \xAF 转义。一个可移植的替代方案可能是 perl -pCSD -e 's/1/\x{2701}/g' - tripleee
@tripleee:没错。bash $'...' 的解决方案确实更优秀。 - rici
这就是答案。它甚至可以与printf一起使用。非常感谢@rici。 - Bruce Strafford
使用 bash(它保证支持 C 转义)而不是 sed(它只有作为 GNU 扩展的转义)是一个好主意。 - abarnert
@abarnert:我同意。我只提到sed的事情是因为你对问题的评论和OP的回复。 - rici
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接