![sed eval フラグを使用して、「/U+[0-9A-Fa-f]{4}/」をシェルパイプラインの正しい Unicode 文字に置き換えます。](https://linux33.com/image/99183/sed%20eval%20%E3%83%95%E3%83%A9%E3%82%B0%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%80%81%E3%80%8C%2FU%2B%5B0-9A-Fa-f%5D%7B4%7D%2F%E3%80%8D%E3%82%92%E3%82%B7%E3%82%A7%E3%83%AB%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%AE%E6%AD%A3%E3%81%97%E3%81%84%20Unicode%20%E6%96%87%E5%AD%97%E3%81%AB%E7%BD%AE%E3%81%8D%E6%8F%9B%E3%81%88%E3%81%BE%E3%81%99%E3%80%82.png)
ファイルにリストされている既存の文字を正しく可視化しようとしています/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 */
次のように表示したいと思います。
#define XK_onethird 0x0ab0 /* ⅓ VULGAR FRACTION ONE THIRD */
#define XK_twothirds 0x0ab1 /* ⅔ VULGAR FRACTION TWO THIRDS */
#define XK_onefifth 0x0ab2 /* ⅕ VULGAR FRACTION ONE FIFTH */
私は試した:
$ sed -e 's/U+\([0-9A-Fa-f]\{4\}\)/\u\1/' < /usr/include/X11/keysymdef.h
これは単に「無視」されます\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
(注:上記のバリエーションも試しましたprintf
。変更はありません。)
私は何を見逃していますか?評価フラグが利用できない理由sed
そうですか?
編集:この問題は他の言語/ツールで解決することができ、while read echo eval
(+ 1d)答えてくれてありがとう。
しかし、私がこの問題に最も興味を持っているのは解決策です。sed
または、上記のコマンドがこの出力を生成する理由および/またはこれが不可能な理由を調べてください。
答え1
パールの使用:
perl -CS -pe 's/\bU\+([\dA-Fa-f]{4})\b/chr(hex($1))/eg' /usr/include/X11/keysymdef.h
これはPerlにを見つけて16進数にU+0000
変換し、0000
その数字が表す文字に置き換えるように指示します。
ファイルの内容を変更するには、次のようにします。
perl -i -CD -pe 's/\bU\+([\dA-Fa-f]{4})\b/chr(hex($1))/eg' /path/to/file
答え2
(修正された)sed出力を1行ずつ渡しますecho -e ""
。
sed -e 's/U+\([0-9A-Fa-f]\{4\}\)/\\u\1/' </usr/include/X11/keysymdef.h |
while read -r line;do echo -e "$line";done