mots quotidiens.
Daichi Mochihashi (持橋大地) daichi <at> ism.ac.jp by hns, version 2.10-pl1.

先月 2024年05月 来月
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

2006年12月04日(月) [n年日記]

#1 Natural Order in Unix

モデルなどの名前に "model.9" "model.10" .. などと数字を付けることは クラスタリング等でよくあると思いますが, この間IWSLT関係の仕事で, "model.0"〜"model.19" という名前がついたファイルを, それぞれ "model.1"〜"model.20" にリネームする必要があった。
こういう複雑なリネームには, Camel Book のP.426にあるperlの万能スクリプト rename を使って
for f in model.*; do
rename 's/\.(\d+)$/".".($1+1)/e' $f
done
とすればいいですが(マニアック!), 実は上のファイル名グロブ "model.*" は普通は 文字列としてソートされるため, "model.1" "model.10" "model.11" .. "model.2" のように展開されてしまうので, 上ではうまく行かない(ファイルがどれか失くなってしまう)。
Unixの "sort -n" は名前が全て数字の場合にはうまく働くが, 上の場合のように 文字列と混合されている場合には働かない。

ごく一般的に, 数字を含んだファイル名を数値の部分を考慮して並べたいことは よくあると思いますが, Macintosh System7 には数字を含んだ文字列を「自然に」ソートする ための Stuart Cheshire 氏による"Natural Order" という素晴らしいINITが1994年頃 からあって (上の画像), 機能拡張フォルダに入れておくだけで, システムの文字列比較関数を書き換えて, Finder等のファイルが期待した通りに並ぶようになる。
[Natural Order Numerical Sorting]

これには上の画像にあるようにソースが付いているので, 前からやろうと思っていた 通り, 週末にちょっと工作して Unix で使えるようにしよう.. と思って 少し調べたら, すでに誰かがやっていた;。まあ確かに, ごく自然に 考えつきそうなことではあるけれども..。
[Natural Order String Comparison] by Martin Pool 氏。
このページには perl, C, Haskell, Ruby, Python, Java, Javascript による実装例 が載っていて, GNU ls では, "--sort=version" を指定すると常に natural order ソートになるらしい。確認したところ, 確かにそうなる模様。
ただ, 上のファイル名グロブはシェルが行うものなので, 後は zsh にパッチを当てれば いいかな.. と思って下調べをしたら, これもすでにオプションが存在していた。 ガーン。;;

setopt numericglobsort
としておくと, 最初の例のようなファイル名展開が "model.1" "model.2" .. "model.10" のように「自然な」順番になる模様。 これはX68000版の zsh のマニュアルに含まれる zshintro.jp に書いてあるので 読んでいたはずなのだが, 何となく見落としていたらしい。(;_;)
Stuart Cheshire 氏の「Natural Order」は1994年で, Martin Pool氏のページは 2000年くらいに独立に作ったページのようですが, zsh には1994年の時点で既に numericglobsort のオプションは組み込まれていたようなので, zsh ユーザの慧眼に 改めて驚いた。

というわけで, まとめると

という手順で, Unix でも "Natural Order" によるソートを使うことができるようです。


*1: 上のページには GNU textutils の sort(1) に対するパッチもあるようですが, 今は sort(1) は GNU coreutils に含まれていて, アップデートの度に 毎回パッチを追従させるのは手間なので, 自分で別コマンドにして用意しておくとよさそうです。

1 days displayed.
タイトル一覧
カテゴリ分類
 なかのひと
Powered by hns-2.10-pl1, HyperNikkiSystem Project