今回は並べ替え、つまりソートを行ってみましょう。ソート処理はあちこちで使われます。学校なら成績順やあいうえお順、会社なら商品別の売上順や商品番号、ID順などいろいろあります。
プログラムの世界だとソートはアルゴリズムが話題にされる事があります。ソートのアルゴリズムはプログラマにとっては格好のネタなので検索すると色々な方法があるのがわかります。興味ある方は実際に作ってみると面白いかもしれません。
とは言え自動的にデータを取得し、ソートしてリアルタイムにグラフを生成してモニタに表示するなど、用途によってはsortコマンドを利用した方が便利な時もあるかもしれません。sortコマンドはUNIX系OSだけでなくWindowsにもありますが、今回はUNIX系のsortコマンドについて説明します。
今回もこれまでのようにサンプルで利用するファイル・ディレクトリはデスクトップのsampleディレクトリとしています。デスクトップにsampleディレクトリがない場合は作成しておいてください。(コマンド入力ならmkdir ~/Desktop/sampleとして作成することができます)
また、カレントディレクトリも上記の場所になります。cd ~/Desktop/sampleのようにコマンドを入力してカレントディレクトリを変更しておけばよいでしょう。
整数値をソート
まずは簡単なところで整数値を昇順にソートしてみましょう。ここでは、以下のようなデータを用意しました。1から9までの重複のないデータです。数値は一行に1つで数値の後には改行が入っています。
1.txt
6
4
9
2
8
5
1
3
7
このファイルはデスクトップ上にあるsampleディレクトリ内に1.txtという名前になっています。コマンドで内容を確認する場合はcatコマンドやlessコマンドを使います。
cat 1.txt
内容を確認したら昇順にソートしてみましょう。以下のようにコマンドを入力します。
sort 1.txt
すると一応期待通りの結果にソートされています。今度は逆順、つまり降順にソートしてみましょう。降順にソートするにはrオプションを指定します。reverseの頭文字rなので覚えやすいでしょう。
sort -r 1.txt
ここでも一応期待通りの結果になっています。先ほどの結果も今回の結果も一応と書いたのには理由があります。
今度は以下のように少し(2ヶ所)だけ変えたファイル(2.txt)を用意します。
2.txt
16
4
9
12
8
5
1
3
7
先ほどと同様にsortコマンドを実行してみます。すると以下のように期待とは違う結果になってしまいます。
sort 2.txt
どうしてこうなってしまったのかというと数値のソートではなく文字コード順でソートされてしまったためです。sortコマンドはオプションを指定しないと文字コード順でソートしてしまいます。
数値としてソートするにはnオプションを指定します。つまり、数値としてソートしたい場合は以下のようにします。
sort -n 2.txt
小数値をソート
今度は期待通りの結果になりました。数値と言っても整数値だけのソートでは温度など小数値を含む場合に役立ちません。そこで、先ほどの数値を少し変更して小数値を含むデータを用意してソートしてみましょう。用意したデータファイルは3.txtというファイル名とします。
3.txt
1.6
1.4
9
1.25
0.8
1.05
1
3
7
先ほどと同様にnオプションを指定してソートさせてみましょう。
sort -n 3.txt
小数値を含む場合でも正しくソートされています。とは言え、いずれも正数なので負数を含めてソートできるかもやってみましょう。
今度は負数を含めた以下のようなデータを用意し4.txtというファイル名で保存しておきます。
4.txt
-0.8
1
1.05
-1.25
1.4
1.6
3
7
-9
sortコマンドを使ってソートした結果は以下のようになります。負数でも期待通りにソートされています。さすがに複素数はソートできませんが、通常の用途では問題ないでしょう。
sort -n 4.txt
ソートした結果をファイルに保存するにはリダイレクトを使います。以下のようにするとカレントディレクトリにresult.txtという名前でソートした結果が保存されます。
sort -n 4.txt > result.txt
複数カラムがあるデータをソート
それでは次に複数カラムがあるデータをソートしてみましょう。一般的なデータは1行に複数のデータが記述されている(複数カラム)場合が多いでしょう。
今度は以下のように3列(3カラム)のデータを用意しました。各データは,(カンマ・コンマ)区切りです。CSV形式という名前の方が一般的かもしれません。このファイルをカレントディレクトリに5.txtという名前で用意しておきます。なお、CSV形式の場合は拡張子がcsvという場合もありますが、拡張子の違いでsortコマンドの実行結果は異なることはありません。
5.txt
1,Unix,53
5,CP/M,50
7,TRON,38
4,MS-DOS,41
3,Macintosh,38
2,Windows,37
6,OS/2,35
8,Human68K,36
9,iOS,15
10,AndroidOS,14
これまでのデータとは異なり区切り記号があるのでtオプションで区切り文字を指定する必要があります。sort -t ','のように指定します。
sort -t ',' -n 5.txt
最初のカラムでソートする場合は、これでもよいかもしれませんが、他のカラムでソートする場合は、どうしたらいいのでしょう。この場合はkオプションを使ってソート対象にするカラム番号を指定します。最初のカラムが1、次が2、その次が3という番号になります。以下のようにすると2番目の内容をソートします。この場合、英文字の文字コード順にソートされます。
sort -t ',' -k 2 5.txt
文字コード順でソートされては困る場合は以下のように数値の後にnをつけます。
sort -t ',' -k 3n 5.txt
逆順・降順に並び替える
これまでは昇順にソートしましたが、場合によっては逆順・降順にソートしたい場合もあります。逆順にソートするには-rを指定します。
まずは、最初に使った1.txtファイルを逆順にソートしてみましょう。
sort -r 1.txt
期待通りの結果になっています。それは今度は先ほど使用した5.txtのCSVデータの最初のカラムを逆順にソートしてみます。
sort -r -t ',' -n 5.txt
期待通りの結果になっています。今度は2カラム目を逆順にソートしてみましょう。
sort -r -t ',' -k 2 5.txt
これも期待通りの結果になっています。
ところで、すでにソートされている場合は再びソートする必要はありません。sortコマンドはすでにソート済みなのかどうかを調べることができます。これはcオプションを指定するとソート済みかどうかがわかります。すでにソート済みの場合は何も表示されませんが、未ソートの場合はメッセージが表示されます。
例えば先ほど使用した4.txtはソートされていませんが、ソート結果を保存したresult.txtはソート済みです。それぞれsort
-cとすると以下のようになります。