[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-talk
Subject:    Re: Create a directories list with sub-directories
From:       Vadim Nasardinov <vadimn () redhat ! com>
Date:       2004-03-23 15:06:01
Message-ID: 200403231010.31762 () vadim ! nasardinov
[Download RAW message or body]

On Tuesday 23 March 2004 06:14, Dirk Einecke wrote:
> Message-Id: <c3p66c$29fo39$1@ID-43561.news.uni-berlin.de>
> X-Mail-Count: 95603
> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113
> 
> I've a problem. How can I create a directory list with all 
> sub-directories and files like this:
> 
> |- root
>     |- folder1
>        |- filex
>     |- folder2
>        |- folderx
>           |- file1
>        |- filex
>        |- filey
> 
> At the moment I've only a way to read one directory and print the 
> directories and files therein. But that is not enough. Can anybody help 
> me or give me a hint where I can helpfull examples?

As others pointed out, you can use the Find module.  Its
implementation is pretty short and worth taking a look at. On an
RPM-based system, you'll find it in:

$ rpm -ql ruby-libs | grep find.rb
/usr/lib/ruby/1.8/find.rb

If you really want to output an indented tree-like view of a directory
along with its subdirectories, then the Find module may not be the
best tool insofar as it produces a "flattened" view of your directory
structure.  You'll have to do some additional work to "unflatten" it
back into a tree structure.  Because of this, you may be better off
performing your own directory traversal rather than relying on Find.
Something along the following lines will give you an indented view:

#!/usr/bin/ruby

WSIndent    = "   "
LinedIndent = "|  "
DirIndent   = "+- "

def dirTree(dir, indent)
    files = []
    dirs =  []

    Dir.foreach(dir) do |ff|
        path = File.join(dir, ff)
        # Note: this doesn't follow symlinks
        if File.directory?(path)
            dirs.push(ff) if  ff[0] != ?.
        else
            files.push(ff)
        end
    end

    dirs.sort!
    files.sort!
    fileIndent = indent + (dirs.length > 0 ? LinedIndent: WSIndent)
    files.each do |ff|
        puts "#{fileIndent}#{ff}"
    end

    return if dirs.length == 0

    if dirs.length > 1
        nextIndent = indent + LinedIndent
        thisIndent = indent + DirIndent
        dirs[0..-2].each do |dd|
            puts "#{thisIndent}#{dd}/"
            dirTree(File.join(dir, dd), nextIndent)
        end
    end
    puts "#{indent + DirIndent}#{dirs[-1]}/"
    dirTree(File.join(dir, dirs[-1]), indent + WSIndent)
end

ARGV.each do |dd|
    puts "+#{dd}"
    dirTree(dd, "")
end

# The end ==================================================



The output from this script looks like this (best viewed with a
fixed-width font):

./tree.rb /usr/lib/ruby/1.8/
+/usr/lib/ruby/1.8/
|  English.rb
|  Env.rb
|  base64.rb
|  benchmark.rb
+- bigdecimal/
|     jacobian.rb
|     ludcmp.rb
|     newton.rb
|     nlsolve.rb
+- cgi/
|  |  session.rb
|  +- session/
|        pstore.rb
+- date/
|     format.rb
+- dl/
|     import.rb
|     struct.rb
|     types.rb
|     win32.rb
+- drb/
|     drb.rb
|     eq.rb
|     extserv.rb
|     extservm.rb
+- i386-linux-gnu/
|  |  bigdecimal.so
|  |  config.h
|  |  curses.so
|  |  dbm.so
|  +- digest/
|  |     md5.so
|  |     rmd160.so
|  |     sha1.so
|  |     sha2.so
|  +- io/
|  |     wait.so
|  +- racc/
|        cparse.so
+- io/
|     nonblock.rb

... elided for brevity's sake ...

+- webrick/
|  |  accesslog.rb
|  |  compat.rb
|  |  config.rb
|  |  cookie.rb
|  +- httpauth/
|  |     authenticator.rb
|  |     basicauth.rb
|  |     digestauth.rb
|  |     htdigest.rb
|  +- httpservlet/
|        abstract.rb
|        cgi_runner.rb
|        cgihandler.rb
|        erbhandler.rb
+- xmlrpc/
|     base64.rb
|     client.rb
|     config.rb
|     create.rb
+- yaml/
      baseemitter.rb
      basenode.rb
      constants.rb
      dbm.rb


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic