言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

スクリプトな日常

僕はこういった日常的なファイルの処理にプログラミング言語を使うのは非常に大事だと思っている。もしかしたら頑張ったらエディタの機能で出来たり、そういう事が出来るフリーソフトがあったり、勿論手でやった方が早いかも知れないが、プログラミング言語を使う事の柔軟性と再利用性は多くの人に魅力的なはずだ。その意味で、Squeak でこういう事がもっと簡単に書けたら良いなと思う。他の言語ではどうなるのだろうか。問題を整理する

  • あるぐちゃぐちゃしたフォルダがある。
  • 必要なファイルは 名前.バージョン番号.pr の形式をしている (バージョン番号は数字三文字)
  • 必要なファイルの中から最新バージョンの物を抜き出し
  • 最終更新の日付ごとに分けてディレクトリに入れたい。
  • ディレクトリに入れるのは rename を使う(コピーだとファイル更新日が変わるので)
dir := (FileDirectory on: 'C:\takasi\tmp\').

allProjects :=
	dir entries select: [:each | '*.###.pr' match: each name]

projectNames :=
	(allProjects collect: [:each | each name allButLast: '.###.pr' size]) asSet.

newestProjectBlock :=
	[:prName :projects | ((projects select: [:each | prName, '.*' match: each name])
		asSortedCollection: [:a :b | a name > b name]) first].

newestProjects :=
	projectNames collect: [:prName | newestProjectBlock value: prName value: allProjects].

newestProjects do: [:entry |
	dateDirName := (TimeStamp fromSeconds: entry modificationTime) date yyyymmdd.
	dir assureExistenceOfPath: dateDirName.
	dir rename: entry name toBe: dateDirName, '\', entry name]

さあ、これを Ruby で書いてみよう!多分 Ruby に詳しい人が書いたらもっと滅茶苦茶短くなると思うけどこの辺で勘弁を。glob や正規表現が使えるのはやっぱ楽だな。なぜ newestProjects に nil が入ってしまうのかは謎。しかしこれに費やした時間を考えると手でやった方が早かった。本末転倒。

dirName = 'C:/takasi/tmp/'
allProjects =  Dir.glob(dirName + '*.???.pr');

projectNames = allProjects.collect{|each|
    each.gsub(/(.*)\.\d\d\d.pr/, '\1')}

newestProjects = projectNames.uniq.collect{|each|
    (Dir.glob(each+'.???.pr')).sort.reverse[0]}

newestProjects.each{ |each|
	if each then
        dateDirName = dirName + File.mtime(each).strftime('%Y-%m-%d')
        Dir.mkdir(dateDirName) unless File.exist?(dateDirName)
		File.rename(each, dateDirName + '/' + File.basename(each))
	end
	}