From: Vadim Nasardinov Date: 2004-03-24T00:06:01+09:00 Subject: Re: Create a directories list with sub-directories On Tuesday 23 March 2004 06:14, Dirk Einecke wrote: > Message-Id: > 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