ちょっと前に、Twitter上でシェル芸を使って漢数字ソートをするという内容があったので、備忘として残しておく。 そもそも、普通に漢数字をソートした場合はUnicodeのハッシュでソートされるのだが、その順番はバラバラになってしまう。

blacknon@BS-PUB-DEVELOP:~$ echo "一二三四五六七八九〇" | grep -o . | sort
〇
一
九
五
三
四
七
二
八
六

これは、文字コード策定の際に画数の少ない順で振られているとか、色々と事情があるようだ。 まぁ確かに、「one,two,three...」と記述してsortしても順番どおりには並ばないし、同じようなことかな。

事情はどうであれ、このままでは順番どおりにsortはできない。 じゃあどうするかというと、以下のようなやり方が考えられる。

1. 事前に順番を定義しておく

通常のsortも、Unicodeなりのコード順に並んでいるわけなので、事前に文字ごとの順番を定義しておく事で対処ができる。 例として、以下のように事前に順番を指定した文字列を出力させ(3行目)、それをsort対象となる行(2行目)にjoinさせることで対応できる。

join -2 2 -a1 \
    <(echo 三三七上一八六九四下二上五|grep -o .|sort) \
    <(echo 一二三四五六七八九十上中下|grep -o .|nl|sort -k2) \
|sort -k2n|awk '{print $1}'
blacknon@BS-PUB-DEVELOP:~$ join -2 2 -a1 \
>     <(echo 三三七上一八六九四下二上五|grep -o .|sort) \
>     <(echo 一二三四五六七八九十上中下|grep -o .|nl|sort -k2) \
> |sort -k2n|awk '{print $1}'
一
二
三
三
四
五
六
七
八
九
上
上
下

2. ライブラリを使用する

もしくは、ちゃんと漢数字向けに書かれたライブラリを使用してsortする方法だ。 例えば、Perlの場合であればLingua::JA::Numbersというライブラリがあるので、これで漢数字↔アラビア数字を変換してsortしてやればいい。 その他、@ebanさんの解答のようにrubyであればzen_to_iを使うという方法もあるようだ。