ちょっと前に、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を使うという方法もあるようだ。
最初からsort_byでいいじゃん
echo 二五下三九七八中十六四上一 | ruby -rzen_to_i -nle 'puts $_.chars.sort_by{|x|x.zen_to_i.to_i}*""'#シェル芸— eban (@eban) 2017年9月29日