Directory tree traversal fun

Hi,
I want to write a recursive file renamer. It will work such that given
the following:

c:\prov\foo1.txt
c:\prov\fooDir
c:\prov\fooDir\foo2.txt

you call rename(“c:\prov”, “foo”, “bar”) and get

c:\prov\bar1.txt
c:\prov\barDir
c:\prov\barDir\bar2.txt

I wrote the following:

def rename(headOfTree, what, withWhat)
p = Pathname.new(headOfTree)
p.find() do |file|
path = file.to_s #just to make it prettier
File.rename(path, path.gsub("#{what}", withWhat)) if
path.include?(what)
end
end

The problem is that p.find() is top-to-bottom, so it renames in the
following order:

  1. c:\prov\bar1.txt
  2. c:\prov\barDir

Then, it can’t get to c:\prov\fooDir anymore, so it doesn’t rename
c:\prov\fooDir\foo2.txt

Is there a more elegant solution than creating an array with the
names, sort the array length descending and rename? I don’t trust this
approach because it could happen that it reverts the order of some
files.

Is there a way to traverse a directory leaves-first? (bottom-to-top)

On Jun 14, 2007, at 1:47 PM, Jerry Blanco wrote:

Hi,
Hi.

def rename(headOfTree, what, withWhat)
p = Pathname.new(headOfTree)
p.find() do |file|
path = file.to_s #just to make it prettier
File.rename(path, path.gsub("#{what}", withWhat)) if path.include?
(what)
end
end

Is there a way to traverse a directory leaves-first? (bottom-to-top)

def rename( headOfTree, what, withWhat )
p = Pathname.new( headOfTree )
p.each_entry do |file|
path = file.to_s #just to make it prettier
next if path =~ /^..?$/
rename( path, what, withWhat ) if path.directory?
File.rename( path, path.gsub( “#{what}”, withWhat ) ) if
path.include?( what )
end
end

This code is untested, but if you recurse before you rename, you
should get what you want.