読者です 読者をやめる 読者になる 読者になる

ファイル群を特定のパターンでコピーしたい

どういうことかと言うと、まずグロブパターンにマッチするファイル群があってその各々のファイルを特定のルールで別の場所にコピーしたい。例えば、

A_foo.txt
B_bar.txt
C_buz.txt

ってファイルがあって、これを

other/A/foo.txt
other/B/bar.txt
other/C/buz.txt

みたいにしたいと。ルールはパスの置換程度でいい。
で、コピー自体何回かやるしあとでパターンも増えるんでスクリプト書こうと思い、taskでコピーしたいパターンを選択とかできると便利かと思ってなんとなく練習がてら Rake で書いてみることにした。
最初は rule とか使えば書けるとかなーとか考えて、まずは素直に

SRC = FileList[pat]
DEST = SRC.gsub(/pat/, 'rep')

とか書き始めたんだけど、依存の順序のせいか rule タスクで書こうと思うとどうしてもうまく書けなかった。う〜む。



で、ない知恵絞った結果、



なぜかこういう風になった。

def copytask(name, pat, &gsub)
  task name => FileList[FileList[pat].to_a.map do |f|
    out = gsub.call(f)
    dir = out.pathmap('%d')
    directory dir
    file out => [f, dir] do
      cp f, out
    end
    out
  end]
end

こんな感じで使う。

copytask :hoge, "#{SRC_DIR}/*.txt" do |f|
  f.gsub(/#{SRC_DIR}\/([A-Z])_(\w*)/, '/other/\1/\2')
end

問題点としては、desc が付けられない。まあ Rake の API 直接叩けばいけるんだろうけど面倒だったし今回は別にいらんかったのでやらなかった。
というかそもそもアプローチとしてこの方法は正しいのかがよくわからない。
とりあえず目的は果たせたしいーかと思いつつもっとスマートな方法もありそうな気がしてならない。というわけですごい人教えてください!



…ところでやってる途中で知ったんだけど FileList#gsub ってブロック渡せないんだね。何これ手抜き?