最近、bash における sort の使い方について学ぶ機会がありましたので記載します。(下地先生、ご指導ありがとうございます!)
学んでいく中で、manpagesの日本語訳についてもちょっと思うところがありましたので、それも踏まえて述べていきます。
sort は文字通り「並べ替え」をするコマンドです。
しかし、数字に関しては、以下のような現象が起きます。
seq 20 により、1から20まで数字を羅列したものに対して sort をかけてみます。
$seq 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$ seq 20 | sort 1 10 11 12 13 14 15 16 17 18 19 2 20 3 4 5 6 7 8 9
これで、デフォルトの sort の動きがわかります。まず最初の1文字をみてソートするわけですね。なので、今の場合、1の次に10が来てしまうわけです。
これを避けるのが sort -n です。
$ seq 20 | sort -n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
正しく並べ替えられました。
ここで、man sort で、sort -n の説明を見てみました。
日本語の man では以下のように説明されていました。
[blockquote]
-n, –numeric-sort
文字列を数値とみなして比較する
[/blockquote]
文字列を数値とみなして比較する?
英語にあたってみました。manを英語でみたいときは、
LANG=C; man sort
で英語を見ることができます。
[blockquote]
-n, –numeric-sort
compare according to string numerical value
[/blockquote]
“string numerical value” がポイントですね。
数値を文字列のルールに従って比較する
がより適切な訳かと思いました。
つまり、数値でのソートならば
1
2
10
は
1
10
2
が適切なわけですが、「文字列」としての扱いだと、
aの次にbが来るように
1の次には2が来る ということを英語で言いたいのではないかなと感じました。
それでは、この結果をひっくり返したいと思います。sort は降順は -r です。
$ seq 20 | sort -n | sort -r 9 8 7 6 5 4 3 20 2 19 18 17 16 15 14 13 12 11 10 1
sort -n で一度きれいにしても、 sort -r をすると、純粋に数字だけでの比較になるので、またぐちゃぐちゃになります。
これを解決するのが、 sort -nr になります。
いま、冗長ですが、sort -n と sort -nr を組み合わせてみます。
(実際は、sort -n は不要です)
$ seq 20 | sort -n | sort -nr 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
きちんときれいになりました。
ということで、今回の学びは、
sort -n および sort -nr は、数値のかたまりを文字列として扱うことによって、人間にとって自然な並び替えをする ということでした。