# Recursive directory listing

**URL:** <https://www.ruby-forum.com/t/recursive-directory-listing/104465>\
**Category:** Ruby\
**Created:** [May 18, 2007, 11:21am UTC](https://www.ruby-forum.com/t/recursive-directory-listing/104465 "2007-05-18T11:21:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jesper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/49beb7/32.png) [@Jesper](https://www.ruby-forum.com/u/Jesper)\
**Post date:** [May 18, 2007, 11:21am UTC](https://www.ruby-forum.com/t/recursive-directory-listing/104465/1 "2007-05-18T11:21:52Z")

</div>

Hello,

I’ve made a small script that gets username + password from a form, and  
uses them to log into an ftp-account, where it then search for specific  
files (\*.mp3, for example).

I read somewhere (online, not in the Pickaxe which is out of reach at  
the moment), that “\*\*/\*.mp3” would search through all levels, looking  
for \*.mp3 files… but that doesn’t seem to be the case. My (pig-ugly)  
code at the moment looks something like:

lines = ftp.nlst("_.mp3 \*\*/_.mp3 \*\*_/_.mp3 \*\*\*_/_.mp3")

It gets very bloated when I want to find many different extensions many  
(all) levels down, surely there is some better way to do this? Any hints  
of references would be appreciated.

Regards,

/ J

---

<div class="post-metadata">

**Author:** ![Jesper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/49beb7/32.png) [@Jesper](https://www.ruby-forum.com/u/Jesper)\
**Post date:** [May 18, 2007, 11:26am UTC](https://www.ruby-forum.com/t/recursive-directory-listing/104465/2 "2007-05-18T11:26:53Z")

</div>

In message [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), Jesper writes:

> I read somewhere (online, not in the Pickaxe which is out of reach at  
> the moment), that “\*\*/\*.mp3” would search through all levels, looking  
> for \*.mp3 files… but that doesn’t seem to be the case. My (pig-ugly)  
> code at the moment looks something like:

It seems to me that this might be a feature of some _shells_, but  
I’ve never seen it in Ruby.

> It gets very bloated when I want to find many different extensions many  
> (all) levels down, surely there is some better way to do this? Any hints  
> of references would be appreciated.

You will almost certainly have to actually write the code to list, look  
for directories, change to them, and recurse.

-s

---

<div class="post-metadata">

**Author:** ![Jesper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/49beb7/32.png) [@Jesper](https://www.ruby-forum.com/u/Jesper)\
**Post date:** [May 18, 2007, 12:00pm UTC](https://www.ruby-forum.com/t/recursive-directory-listing/104465/3 "2007-05-18T12:00:55Z")

</div>

On 18.05.2007 11:26, Peter S. wrote:

> In message [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), Jesper writes:
> 
> > I read somewhere (online, not in the Pickaxe which is out of reach at  
> > the moment), that “\*\*/\*.mp3” would search through all levels, looking  
> > for \*.mp3 files… but that doesn’t seem to be the case. My (pig-ugly)  
> > code at the moment looks something like:
> 
> It seems to me that this might be a feature of some _shells_, but  
> I’ve never seen it in Ruby.

Then you’ve never used Dir[] or Dir.glob().

11:51:25 [~]: ruby -e ‘puts Dir[“/usr/lib/\*\*/\*.{h,so}”]’  
/usr/lib/ruby/1.8/i386-cygwin/config.h  
/usr/lib/ruby/1.8/i386-cygwin/defines.h  
/usr/lib/ruby/1.8/i386-cygwin/dl.h  
/usr/lib/ruby/1.8/i386-cygwin/dlconfig.h  
/usr/lib/ruby/1.8/i386-cygwin/dln.h  
/usr/lib/ruby/1.8/i386-cygwin/env.h  
/usr/lib/ruby/1.8/i386-cygwin/intern.h  
/usr/lib/ruby/1.8/i386-cygwin/missing.h  
/usr/lib/ruby/1.8/i386-cygwin/node.h  
/usr/lib/ruby/1.8/i386-cygwin/re.h  
/usr/lib/ruby/1.8/i386-cygwin/regex.h  
/usr/lib/ruby/1.8/i386-cygwin/ruby.h  
/usr/lib/ruby/1.8/i386-cygwin/rubyio.h  
/usr/lib/ruby/1.8/i386-cygwin/rubysig.h  
/usr/lib/ruby/1.8/i386-cygwin/st.h  
/usr/lib/ruby/1.8/i386-cygwin/util.h  
/usr/lib/ruby/1.8/i386-cygwin/version.h  
/usr/lib/engines/lib4758cca.so  
/usr/lib/engines/libaep.so  
/usr/lib/engines/libatalla.so  
/usr/lib/engines/libchil.so  
/usr/lib/engines/libcswift.so  
/usr/lib/engines/libgmp.so  
/usr/lib/engines/libnuron.so  
/usr/lib/engines/libsureware.so  
/usr/lib/engines/libubsec.so  
/usr/lib/ruby/1.8/i386-cygwin/bigdecimal.so  
/usr/lib/ruby/1.8/i386-cygwin/curses.so  
/usr/lib/ruby/1.8/i386-cygwin/dbm.so  
/usr/lib/ruby/1.8/i386-cygwin/digest.so  
/usr/lib/ruby/1.8/i386-cygwin/dl.so  
/usr/lib/ruby/1.8/i386-cygwin/enumerator.so  
/usr/lib/ruby/1.8/i386-cygwin/etc.so  
/usr/lib/ruby/1.8/i386-cygwin/fcntl.so  
/usr/lib/ruby/1.8/i386-cygwin/gdbm.so  
/usr/lib/ruby/1.8/i386-cygwin/iconv.so  
/usr/lib/ruby/1.8/i386-cygwin/nkf.so  
/usr/lib/ruby/1.8/i386-cygwin/openssl.so  
/usr/lib/ruby/1.8/i386-cygwin/pty.so  
/usr/lib/ruby/1.8/i386-cygwin/readline.so  
/usr/lib/ruby/1.8/i386-cygwin/sdbm.so  
/usr/lib/ruby/1.8/i386-cygwin/socket.so  
/usr/lib/ruby/1.8/i386-cygwin/stringio.so  
/usr/lib/ruby/1.8/i386-cygwin/strscan.so  
/usr/lib/ruby/1.8/i386-cygwin/syck.so  
/usr/lib/ruby/1.8/i386-cygwin/syslog.so  
/usr/lib/ruby/1.8/i386-cygwin/tcltklib.so  
/usr/lib/ruby/1.8/i386-cygwin/tkutil.so  
/usr/lib/ruby/1.8/i386-cygwin/Win32API.so  
/usr/lib/ruby/1.8/i386-cygwin/win32ole.so  
/usr/lib/ruby/1.8/i386-cygwin/zlib.so  
/usr/lib/ruby/1.8/i386-cygwin/digest/md5.so  
/usr/lib/ruby/1.8/i386-cygwin/digest/rmd160.so  
/usr/lib/ruby/1.8/i386-cygwin/digest/sha1.so  
/usr/lib/ruby/1.8/i386-cygwin/digest/sha2.so  
/usr/lib/ruby/1.8/i386-cygwin/racc/cparse.so  
11:51:34 [~]:

> > It gets very bloated when I want to find many different extensions many  
> > (all) levels down, surely there is some better way to do this? Any hints  
> > of references would be appreciated.
> 
> You will almost certainly have to actually write the code to list, look  
> for directories, change to them, and recurse.

Yep, guess so. Documentation of Net::FTP does not mention path globbing  
like Dir[] does.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Jesper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/49beb7/32.png) [@Jesper](https://www.ruby-forum.com/u/Jesper)\
**Post date:** [May 18, 2007, 5:30pm UTC](https://www.ruby-forum.com/t/recursive-directory-listing/104465/4 "2007-05-18T17:30:40Z")

</div>

In message [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), Robert K. writes:

> Then you’ve never used Dir[] or Dir.glob().

True enough. Convenient!

-s

---

<div class="post-metadata">

**Author:** ![Jesper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/49beb7/32.png) [@Jesper](https://www.ruby-forum.com/u/Jesper)\
**Post date:** [May 18, 2007, 8:07pm UTC](https://www.ruby-forum.com/t/recursive-directory-listing/104465/5 "2007-05-18T20:07:01Z")

</div>

On May 18, 10:59 pm, vasudevram [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > files (\*.mp3, for example).  
> > of references would be appreciated.  
> > port it to Ruby. (I think the Python version even supports the prune
> 
> Vasudev Ram  
> Dancing Bison Enterpriseswww.dancingbison.com- Hide quoted text -
> 
> - Show quoted text -

P.S.: Forgot to mention that what I’ve suggested is the same as what  
Peter S. said in his first reply to your post - a file tree walk  
does just what he said.

The C ftw() function, if I remember, supports the ability to pass a  
function pointer to it, via which the function pointed to, gets called  
for each entry in the tree (recursively). Providing the ability to  
pass a block that can do the same (in your Ruby version, if you do  
write one), might be a good idea …

- Vasudev

---

<div class="post-metadata">

**Author:** ![Jesper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/49beb7/32.png) [@Jesper](https://www.ruby-forum.com/u/Jesper)\
**Post date:** [May 18, 2007, 8:01pm UTC](https://www.ruby-forum.com/t/recursive-directory-listing/104465/6 "2007-05-18T20:01:00Z")

</div>

On May 18, 2:20 pm, Jesper [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> lines = ftp.nlst(“_.mp3 \*\*/_.mp3 \*\*_/_.mp3 \*\*\*_/_.mp3”)
> 
> It gets very bloated when I want to find many different extensions many  
> (all) levels down, surely there is some better way to do this? Any hints  
> of references would be appreciated.
> 
> Regards,
> 
> / J

You could try to implement the file-tree walk function which is  
available in C libraries that come with the free C compilers like GCC;  
if I remember right, its called ftw(). Or an easier option could be to  
look at the source for the similar function/method of Python (I think  
there is one, since I was reading this in a Python book lately) and  
port it to Ruby. (I think the Python version even supports the prune  
option as in the UNIX find command). I don’t think it should be too  
difficult and, though doing so would be an additional investment of  
time, its likely to stand you (and others, if you release the code for  
it) in good stead later as well, as walking a file tree is a common  
and generic need. If you’re doing it, try to let it support blocks, so  
as to be more Rubyish (and useful) 🙂

Maybe I’ll try to do it myself when I get some free time …

My 2c …

Vasudev Ram  
Dancing Bison Enterprises

> **[dancingbison.com](http://ww38.dancingbison.com/)**
>
> Learn Python Programming
