Recursive directory listing

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

In message [email protected], 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

On 18.05.2007 11:26, Peter S. wrote:

In message [email protected], 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

In message [email protected], Robert K. writes:

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

True enough. Convenient!

-s

On May 18, 10:59 pm, vasudevram [email protected] 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

On May 18, 2:20 pm, Jesper [email protected] 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) :slight_smile:

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

My 2c …

Vasudev Ram
Dancing Bison Enterprises