ディレクトリの平坦化

30分プログラム、その249。ディレクトリの平坦化。
あるディレクトリとその子孫に含まれるファイルをひとつのディレクトリに集めるスクリプト
特に意味はないんだけれども、思いついたので。ただ単に書くだけではつまらないので、Rubyコーディング規約に従って書いてみる。

ところでこれ、zshなら

$ mv **/*(.) .

とすればできたりする。あるいはfindとxargsあたりを組み合せればできるような気がしてる。

使い方

$ tree
.
`-- a
    |-- b
    |   |-- bar
    |   `-- foo
    `-- foo

2 directories, 3 files

$ ./flat.rb a

$ tree
.
|-- a
|   `-- b
|-- bar
|-- foo
`-- foo(0)

2 directories, 3 files

ソースコード

require "pathname"
require "fileutils"

class Pathname
  def descent
    return Pathname.glob(self+"**/*")
  end
end

def alt_name(path,name,ext,n=0)
  new_name = path + ("#{name}(#{n})#{ext}")
  if new_name.exist? then
    return alt_name(path,name,ext,n+1)
  else
    return new_name
  end
end

paths = ARGV.map {|arg| Pathname.new(arg).descent }.flatten.select{|x| x.file? }

paths.each do|path|
  case path.basename.exist?
  when true
    name = alt_name(Pathname.new("."),path.basename(".*"),path.extname)
    FileUtils.mv(path,name)
  else
    FileUtils.mv(path,path.basename)
  end
end