# Recursive directory rename problem

**URL:** <https://www.ruby-forum.com/t/recursive-directory-rename-problem/159580>\
**Category:** Ruby\
**Created:** [February 5, 2009, 11:55pm UTC](https://www.ruby-forum.com/t/recursive-directory-rename-problem/159580 "2009-02-05T23:55:28Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![ransom](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ac8455/32.png) [@ransom](https://www.ruby-forum.com/u/ransom)\
**Post date:** [February 5, 2009, 11:55pm UTC](https://www.ruby-forum.com/t/recursive-directory-rename-problem/159580/1 "2009-02-05T23:55:28Z")

</div>

Problem:

- trying to standardize on a naming convention for all of my  
directories(OS agnostic).
- new structure should be all lower-case with hyphphens for spaces
- Using windows, I am running the following:

Dir.foreach("./"){ |d|  
next if d =~ /[a-z]+.[a-z]+/  
next if d == “.” or d == “…”  
d.downcase!  
newfile = d.gsub(/\W/, “-”)  
File.rename(d, newfile)  
}

so I want:

\Test Dir1  
\TestDir2\TestDir 1

to change to

\test-dir1  
\testdir2\testdir-1

Which works fine on the top level, but is not recursing down to the next  
level. Filenames should be ignored.

I’ve tried playing with various methods on the Dir class (entries,  
etc…).  
Using Dir[**/**] is throwing up saying that it can’t rename (no surprise  
since it can’t rename without an absolute path, I guess).

Please help thanks!

---

<div class="post-metadata">

**Author:** ![ransom](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ac8455/32.png) [@ransom](https://www.ruby-forum.com/u/ransom)\
**Post date:** [February 6, 2009, 6:05am UTC](https://www.ruby-forum.com/t/recursive-directory-rename-problem/159580/2 "2009-02-06T06:05:36Z")

</div>

Ransom T.:

> so I want:
> 
> \Test Dir1  
> \TestDir2\TestDir 1
> 
> to change to
> 
> \test-dir1  
> \testdir2\testdir-1
> 
> Which works fine on the top level, but is not recursing down to the  
> next level. Filenames should be ignored.

Dir.entries is not recursive; you want ‘find’. But it has to be a  
depth-first ‘find’: you can gradually replace the pillars of a  
building if you start from the top, but not from the bottom. (Mixing  
metaphors on which direction is ‘depth’.)

require ‘pathname’

def find\_depth\_first(pathname)  
acc = []  
pathname.find { |file| acc \<\< file }  
acc.reverse!  
acc.each { |path| yield path }  
end

find\_depth\_first(Pathname(".")) { |path|  
if path.directory?  
new\_path = path.dirname +  
Pathname(path.basename.to\_s.downcase.gsub(/\s/, “-”))  
if new\_path != path  
path.rename(new\_path)  
end  
end  
}
