msortでデータをソートする
ほとんどのLinuxシステムにインストールされているGNU sortプログラムと比べたとき、ソートキーの所在指定とソート順指定の柔軟性ではmsortが勝る。また、msortは国際化を重視していて、UTF-8を完全サポートするし、ソートキーごとに異なるロケールを用いてファイルをソートできるし、非西欧式の記数法で表された数値もサポートする。
msortには、Gutsy(Ubuntu 7.10)、openSUSE、Fedora 7用のパッケージがあるが、本稿ではバージョン8.44を用いてソースからビルドする。msortビルドにどのような機能を取り入れたいかにより、いくつかの必須もしくは任意の依存関係がある。たとえば、非西欧式の記数法で表された数値を扱うのに、msortはUninumライブラリを使用する。もちろん、この機能が不要なら、Uninumサポートなしでmsortをコンパイルしてよい(Fedora 8といくつかのopenSUSEバージョンにはUninumパッケージがあるが、Gutsyにはない)。msortのグラフィカルインタフェースには、Tcl/Tkとiwidgetsライブラリ(Gutsy、openSUSE 10.3、Fedora 8用がある)が必要である。ソースからmsortをコンパイルするには、通常の「./configure; make; sudo make install
」の手順をたどればよい。msortでUTF-8テキストを扱うには2通りのオプションがある。1つはutf8procパッケージを使うことであり、もう1つはlibicuを使うことである。msortの作者は、utf8procでなくlibicuサポートを使ってコンパイルするよう勧めている。
ソートするデータをレコードに分割することはよく行われる。たとえば、いくつかのテキスト行をソートするとしよう。この場合、各行を1つのレコードとみなして、それぞれの一部をソートキーに指定することができる。たとえば、人名を含んでいるファイルのソートなら、ラストネームに注目して出力の順序を決める、などである。ソートキーだけではデータの完全ソートが保証されないときは、使用できる第2のソートキーを指定しておくとよいだろう。たとえば、第1のソートキーがファイル名のエクステンションなら、第2のソートキーとしてファイル名そのものを使う。こうすると、同じエクステンションを持つすべてのファイルが1つにまとまって出力され、そのファイルどうしの前後関係はファイル名によって決まることになる。
タグ付きデータのファイルがあって、これをソートしたいとする。固定フィールド長を持たない自由形式ファイルをGNU sortで扱うことは簡単ではない。だが、次のmsort呼び出しなら、ラストネームでデータをソートできる。最初の呼び出しでは長い引数名を使用しているが、これは例をできるだけ読みやすくするためで、最後のコマンドでやっているように短い引数オプションを使っても同じソートができる。-l
/--line
オプションは、各行を1つのレコードとして扱うようmsortに指示している。-t
/--tag
オプションは、ソートキーを探すときに正規表現を使えという指示である。
$ cat tagged-data.txt first:Frodo last:Baggins first:Samwise last:Gamgee first:Meriadoc last:Brandybuck first:Peregrin last:Took $ msort.utf8proc --quiet --line --tag last: tagged-data.txt first:Frodo last:Baggins first:Meriadoc last:Brandybuck first:Samwise last:Gamgee first:Peregrin last:Took $ msort.utf8proc -qlt last: tagged-data.txt
msortは、複数行にまたがるレコードも扱える。レコードどうしの分離に特殊文字が使われているときは、--record-separator
コマンドラインオプションを指定し、msortにその文字を使わせることができる。この指定がない場合、msortは2個以上の改行文字の連続をレコード分離記号とみなす。
以下に示すのは上と同じデータだが、レコードが複数の行にまたがっている。ここでは、--block
オプションでレコードが複数行形式になっていることをmsortに伝えたうえで、ラストネームによらず、ファーストネームでソートを実行してみよう。レコードごとにfirstタグとlastタグの順序がまちまちであることに注意してほしい。さらに、Peregrinには新しい値を追加してあるが、これは結果の並び順にまったく影響していない。
$ cat multiline-data.txt first:Frodo last:Baggins last:Gamgee first:Samwise first:Meriadoc last:Brandybuck something else first:Peregrin last:Took $ msort.utf8proc --quiet --block --tag first: multiline-data.txt first:Frodo last:Baggins first:Meriadoc last:Brandybuck something else first:Peregrin last:Took last:Gamgee first:Samwise
次に示すのは、ソートに複数のキーを使うことが望ましい例である。まず、第2列に基づいてソートするが、この列には100という値がいくつもある。したがって、そうしたレコードについては、つづいて第1列に基づくソートを行うと、出力が読みやすくなる。-n
/--position
コマンドラインオプションは、指定のフィールドをキーとしてソートするようmsortに伝えている。フィールド間の分離にはホワイトスペースを使うのがデフォルトであり、第1列と第2列の間のスペースでデータが2つの列に正しく分割される。しかし、-d
/--field-separators
引数を用いて、複数のフィールド分離文字を指定することもできる。コマンドラインの中央にある-c n
オプションは、指定されたキーを数値的にソートせよ、という指示である。デフォルトでは辞書的な比較が行われるため、20という値が100という値の後ろに来ることになるが、ここでは数値比較により、出力のいちばん上に置かれている。
$ cat multi-key-charnum.txt act 100 there 100 foo 100 bar 300 urusai 300 small 20 one 20 $ msort.utf8proc --quiet --line -n 2 -c n -n 1 multi-key-charnum.txt one 20 small 20 act 100 foo 100 there 100 bar 300 urusai 300
-c
で指定できるソート順オプションには、日付、時刻、ドメイン、電子メールアドレス、角度、ハイブリッドなど、さまざまなものがある。数値オプションにも何通りかある。ハイブリッドモードは、テキストと数値の反復パターンに基づいてフィールドを分割するというもので、システムログによくあるIPアドレスのソートに非常に便利なオプションである。次に示すのは、syslogで得たiptablesパケットレポートの部分サンプルである。これを、まずソースアドレスで、次に宛先アドレスでソートしてみよう。-t
/--tag
オプションでログからIPアドレスを拾い出し、-c h
オプションで、どのキーについてもハイブリッド比較モードでのソートを行うよう指示する。
$ cat hybrid-ips.txt Apr 29 20:14:58 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.3.4 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.4 DST=192.168.4.12 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.0.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth1 OUT=eth0 SRC=192.168.3.3 DST=192.168.3.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.4 DST=192.168.0.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.0.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.0.133 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.1.33 LEN=76... $ msort.utf8proc -ql -t SRC= -c h -t DST= -c h hybrid-ips.txt Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.0.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.0.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.0.133 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.1.33 LEN=76... Apr 29 20:14:58 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.2 DST=192.168.3.4 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth1 OUT=eth0 SRC=192.168.3.3 DST=192.168.3.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.4 DST=192.168.0.33 LEN=76... Apr 29 20:15:48 fots kernel: invalides IN=eth2 OUT=eth0 SRC=192.168.3.4 DST=192.168.4.12 LEN=76...
msortでは、ソートキーを--tag
正規表現で指定できるし、そのキーの比較方法をいろいろに選択できる。このため、Perlスクリプトなどの世話にならなくても、直接、コマンドラインから多種多様なソート作業を実行できる。扱うデータの種類によっては、外国語の記数法がサポートされることも大きな利点となる。
Ben Martinは、ファイルシステムに携わって10数年。現在、PH.D.も取得し、libferris、各種ファイルシステム、検索ソリューションを中心にコンサルティング事業を展開している。