220


TwitterのデータのようにJSON形式で取得されたものは、日本語などマルチバイト文字がすべて"\uHHHH"のようなユニコードの16進表現でエンコードされています。  
これをOS Xの標準環境、できればシェルスクリプトで配りたいのですが、この制約の中で出来る良い方法がないか探しています。

当初は、 <http://qiita.com/kumazo@github/items/39500f259500a424800b>  
を参考にして挑戦したのですが、 /usr/bin/printf でもデコードできませんでした。


CC BY-SA 3.0
2014-12-02T01:54:25.307
217
2014-12-16T08:08:39.953
2014-12-03T07:36:10.867
47
248
question
bash macos json decode unicode
エスケープされた日本語文字列をデコードしたい


<https://stackoverflow.com/questions/6319421/do-all-mac-
os-x-10-6-installations-have-perl-installed-by-default>

を読むにOSXでは、perlが使えると思いますので、

<https://stackoverflow.com/questions/8795702/how-to-convert-uxxxx-unicode-to-
utf-8-using-console-tools-in-nix>

の中段にある

[code]

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    binmode(STDOUT, ':utf8');
    
    while (<>) {
        s/\\u([0-9a-fA-F]{4})/chr(hex($1))/eg;
        print;
    }
    
[/code]

<https://stackoverflow.com/a/8796595/718426>

が使えるんじゃないかなと思うのですが、いかがでしょう。


CC BY-SA 3.0
2014-12-02T02:18:10.097
220
2014-12-02T02:18:10.097
2017-05-23T12:38:55.250
-1
351
217
answer


こちらもYosemiteでprintfやechoではデコードできませんでした。 私はいつも以下の方法でデコードしています。

`\uHHHH形式を出力するコマンド | sed -e 's/\\\u\\(....\\)/\&#x\1;/g' | nkf --numchar-
input`

まず"&#xHHHH"の形式に変換してからnkfコマンドで日本語に直しています。 残念ながらnkfはOS
X標準にはなく、brewでインストールしたものですが。。


CC BY-SA 3.0
2014-12-02T02:18:22.700
221
2014-12-02T02:18:22.700
371
217
answer


Python を使ったワンライナーです。OS X はデフォルトで Python 2.7.x が入ってると思うのでそのまま使えると思います。

[code]

    \uHHHH形式を出力するコマンド | python -c "import re; print re.sub(r'\\u[0-9(a-f|A-F)]{4}', lambda x: chr(int(u'0x' + x.group(0)[2:], 16)), raw_input())"
    
[/code]


CC BY-SA 3.0
2014-12-02T10:51:22.717
256
2014-12-02T10:51:22.717
645
217
answer


Pythonならhexとらなくても`decode("unicode-escape")`があります。

[code]

    $ echo '\u30e6\u30cb\u30b3\u30fc\u30c9' | python -c 'from sys import stdin; print stdin.readline().decode("unicode-escape")'
    ユニコード
    
[/code]

* * *

### 追記:

ちなみにサロゲートペアにも対応

[code]

    $ echo '\ud842\udfb7\u91ce\u5bb6' | python -c 'from sys import stdin; print stdin.readline().decode("unicode-escape")'
    野家
    
[/code]


CC BY-SA 3.0
2014-12-02T11:37:04.100
259
2014-12-02T14:32:14.853
2014-12-02T14:32:14.853
62
62
217
answer


perl、python が回答として既に出ているので別解の意味を込めて。

vim が入っているならばバッファにエスケープされた文字列をペーストして

[code]

    :%s/\\u\([0-9a-f]\{4}\)/\=nr2char(eval("0x".submatch(1)),1)/g
    
[/code]

とすれば

[code]

    \u30e6\u30cb\u30b3\u30fc\u30c9
    
[/code]

これが

[code]

    ユニコード
    
[/code]

に変換されます。もし文字列を打ち込むのが難しい場合は

[code]

    $ echo '\u30e6\u30cb\u30b3\u30fc\u30c9' | vim -
    
[/code]

の様にして標準入力を取り込んでも良いと思います。


CC BY-SA 3.0
2014-12-03T14:57:16.280
318
2014-12-03T14:57:16.280
440
217
answer


bash, zsh の組込み echo の -e オプションはどうでしょうか。

[code]

    $ echo -e '\u30e6\u30cb\u30b3\u30fc\u30c9 \ud842\udfb7\u91ce\u5bb6'
    ユニコード 野家
    
[/code]

サロゲートペアな文字は駄目みたいです。


CC BY-SA 3.0
2014-12-16T05:39:37.817
1677
2014-12-16T08:08:39.953
2014-12-16T08:08:39.953
3061
3061
217
answer