用 sed eval 标志在 shell 管道中用正确的 unicode 字符替换“/U+[0-9A-Fa-f]{4}/”

Ale*_*ies 5 character-encoding sed special-characters text-processing unicode

我正在尝试正确可视化/usr/include/X11/keysymdef.h文件中列出的现有字符。

它有如下几行:

#define XK_onethird    0x0ab0  /* U+2153 VULGAR FRACTION ONE THIRD */
#define XK_twothirds   0x0ab1  /* U+2154 VULGAR FRACTION TWO THIRDS */
#define XK_onefifth    0x0ab2  /* U+2155 VULGAR FRACTION ONE FIFTH */
Run Code Online (Sandbox Code Playgroud)

我想将它们显示为:

#define XK_onethird    0x0ab0  /* ? VULGAR FRACTION ONE THIRD */
#define XK_twothirds   0x0ab1  /* ? VULGAR FRACTION TWO THIRDS */
#define XK_onefifth    0x0ab2  /* ? VULGAR FRACTION ONE FIFTH */
Run Code Online (Sandbox Code Playgroud)

我试过:

$ sed -e 's/U+\([0-9A-Fa-f]\{4\}\)/\u\1/' < /usr/include/X11/keysymdef.h
Run Code Online (Sandbox Code Playgroud)

那只是“忽略”了\u. 因此,sed使用 Pilcrow "¶" 将其归结为一些测试用例:

$ echo 00B6 | sed -re $'s/(....)/echo "\u00B6"/e'
¶       # Good, display works, lets get the capture group:
$ echo 00B6 | sed -re $'s/(....)/echo "\u00B6 \\1"/e'
¶ 00B6  # So far, so good, lets prefix \u again:
$ echo 00B6 | sed -re $'s/(....)/echo "\u00B6 \u\\1"/e'
¶ 00B6  # Huh? Ok, trying double-wrapping
$ echo 00B6 | sed -re $'s/(....)/echo "\u00B6 \\u\\1"/e'
¶ 00B6  # Hey, where did the '\\u' go? Ok, try something else:
$ echo 00B6 | sed -re $'s/(....)/echo $(echo "\u00B6 \u\\1")/e'
¶ 00B6  # I give up
Run Code Online (Sandbox Code Playgroud)

(注意:我刚刚也尝试了上面的一些变体printf。没有变化)

我错过了什么?为什么我不能使用这样的评估标志sed

编辑:我知道,这可以while read echo eval用其他语言/工具解决并解决,并感谢(+1d)答案。

但是,对于这个问题,我对解决方案最感兴趣,sed或者知道为什么上述命令会产生此输出和/或为什么不可能。

phe*_*mer 6

使用 perl:

perl -CS -pe 's/\bU\+([\dA-Fa-f]{4})\b/chr(hex($1))/eg' /usr/include/X11/keysymdef.h
Run Code Online (Sandbox Code Playgroud)

这告诉 perl 查找U+0000,将 转换0000为十六进制,然后用该数字表示的字符替换它。

如果要替换文件的内容,可以执行以下操作:

perl -i -CD -pe 's/\bU\+([\dA-Fa-f]{4})\b/chr(hex($1))/eg' /path/to/file
Run Code Online (Sandbox Code Playgroud)

  • 您的解决方案不是很完整。你错过了十六进制数字。`\d` 需要替换为 `(\d|[AF])`。一开始我没有发现它,因为我专注于更换部件和标志。 (2认同)