# Ruby script to rebuild a directory structure

**URL:** <https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500>\
**Category:** Ruby\
**Created:** [April 1, 2009, 11:48pm UTC](https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500 "2009-04-01T23:48:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![emmek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a698b9/32.png) [@emmek](https://www.ruby-forum.com/u/emmek)\
**Post date:** [April 1, 2009, 11:48pm UTC](https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500/1 "2009-04-01T23:48:45Z")

</div>

I have the following problem to solve.

I have some logo images in the following directory structure:

/users/a/adam/logos/jdkajsdns.jpg  
/users/a/alan/logos/skdjaksxa.jpg  
(…)  
/users/b/bob(…)  
(…)  
etc.  
(there are also other directories and files in the structure and some  
directories are empty; but I’d like to extract just the “branch” with  
logo pictures)

Names of directories like “adam”, “alan” are users logins in the  
database. I need to transform that structure into something like this:

/logos/756/jdkajsdns.jpg  
/logos/815/skdjaksxa.jpg  
etc.

where 756 is the id of the user ‘adam’ and the 815 is the id of the user  
‘alan’, etc.

So:

1. It could be possible to bind logins and ids by generating a text file  
with pairs of these values from db and to write a script that transforms  
the structure using such file. How should the proper ruby script look  
like?
2. Is it possible to use script/console in Rails and solve the problem  
just inside it?

---

<div class="post-metadata">

**Author:** ![emmek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a698b9/32.png) [@emmek](https://www.ruby-forum.com/u/emmek)\
**Post date:** [April 2, 2009, 12:27am UTC](https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500/2 "2009-04-02T00:27:18Z")

</div>

Le Wed, 1 Apr 2009 16:48:24 -0500, Emmek On rails a écrit :

> Names of directories like “adam”, “alan” are users logins in the  
> database. I need to transform that structure into something like this:
> 
> /logos/756/jdkajsdns.jpg  
> /logos/815/skdjaksxa.jpg  
> etc.  
> /…/  
> 2) Is it possible to use script/console in Rails and solve the problem  
> just inside it?

Yeps. Something like (completely untested) :

require “fileutils”  
include FileUtils

Users.find(:all).each do |u|  
mkdir “/logos/#{u.id}”  
cp\_r “/users/#{u.login[0…0]}/#{u.login}/logos/.”, “/logos/#{u.id}”  
end

You’ll find what you’re looking for in the FileUtils module :

[http://www.ruby-doc.org/stdlib/libdoc/fileutils/rdoc/index.html](http://www.ruby-doc.org/stdlib/libdoc/fileutils/rdoc/index.html)

Fred

---

<div class="post-metadata">

**Author:** ![emmek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a698b9/32.png) [@emmek](https://www.ruby-forum.com/u/emmek)\
**Post date:** [April 2, 2009, 1:21pm UTC](https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500/3 "2009-04-02T13:21:19Z")

</div>

> Users.find(:all).each do |u|  
> mkdir “/logos/#{u.id}”  
> cp\_r “/users/#{u.login[0…0]}/#{u.login}/logos/.”, “/logos/#{u.id}”  
> end

Thanx for reply. It almost works but… what if a particular user does  
not have logo image or even he doesn’t have path like above? I supposed  
there should be Dir.glob with “empty?” used somewhere in the code.

I wrote something like this:

require “fileutils”  
include FileUtils

User.find(:all,:limit=\>‘20’).each do |u|  
mkdir “public/uploaded/logos/#{u.id}”  
cp\_r “public/uploaded/users/#{u.login[0…0]}/#{u.login}/logo/.”,  
“public/uploaded/logos/#{u.id}” unless  
Dir.glob(“public/uploaded/users/#{u.login[0…0]}/#{u.login}/logo”).empty?  
end

Ugly but it seems to be working.

I have another question: how to force this script to copy only jpg, png  
and gif files from the “logo” directory? (there are also some mouldy php  
files I don’t need ANYMORE)

---

<div class="post-metadata">

**Author:** ![emmek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a698b9/32.png) [@emmek](https://www.ruby-forum.com/u/emmek)\
**Post date:** [April 2, 2009, 6:56pm UTC](https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500/4 "2009-04-02T18:56:01Z")

</div>

Le Thu, 2 Apr 2009 06:20:56 -0500, Emmek On rails a écrit :

> I have another question: how to force this script to copy only jpg, png  
> and gif files from the “logo” directory? (there are also some mouldy php  
> files I don’t need ANYMORE)

Even easier : iterate over Dir.glob(“path/to/orig/\*\*/\*.{jpg,png,gif}”).  
(Add the File::FNM\_CASEFOLD flag as a parameter if you have mixed case.)

Fred

---

<div class="post-metadata">

**Author:** ![emmek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a698b9/32.png) [@emmek](https://www.ruby-forum.com/u/emmek)\
**Post date:** [April 2, 2009, 9:30pm UTC](https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500/5 "2009-04-02T21:30:56Z")

</div>

Le Thu, 2 Apr 2009 13:22:01 -0500, Emmek on Rails a écrit :

> Sorry, what do You exactly mean? I want to copy just images from  
> original location. I’m trying to do something with
> 
> cp\_r “public/uploaded/users/#{u.login[0…0]}/#{u.login}/logo/.”
> 
> but I don’t know what to put at the end of this path to copy just jpgs,  
> gifs and pngs.

It won’t work that way ; cp\_r copies the whole directories. You need to  
use Dir.glob or Find.find to select the files and then copy them one by  
one.

Again, pretty much untested :

Dir.chdir("/public/uploaded/users/#{u.login[0…0]}/#{u.login}/logo")  
do  
Dir.glob("\*\*/\*.{jpg,png,gif}").each do |f|  
f2 = “/public/uploaded/logos/#{u.id}/#{f}”  
mkdir\_p File.dirname(f2)  
cp\_r f, f2  
end  
end

(You’ll need at least to specify absolute paths if public isn’t in the  
root.)

Fred

---

<div class="post-metadata">

**Author:** ![emmek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a698b9/32.png) [@emmek](https://www.ruby-forum.com/u/emmek)\
**Post date:** [April 2, 2009, 8:22pm UTC](https://www.ruby-forum.com/t/ruby-script-to-rebuild-a-directory-structure/164500/6 "2009-04-02T20:22:27Z")

</div>

F. Senault wrote:

> Even easier : iterate over Dir.glob(“path/to/orig/\*\*/\*.{jpg,png,gif}”).  
> (Add the File::FNM\_CASEFOLD flag as a parameter if you have mixed case.)
> 
> Fred

Sorry, what do You exactly mean? I want to copy just images from  
original location. I’m trying to do something with

cp\_r “public/uploaded/users/#{u.login[0…0]}/#{u.login}/logo/.”

but I don’t know what to put at the end of this path to copy just jpgs,  
gifs and pngs.
