Setting recursion depth

Hi all,

I have done some Googling regarding setting the depth of recursive
search in a ruby script and all I have identified is File-Find. Is this
all that can help me?

Basically I want to be able to specify the depth my script will work so
if the depth is 4, the script will look at all items from the root to 4
folders deep e.g

Root
Folder 1
Folder 2
Folder 3

Any input is much appreciated.

Hello,

Basically I want to be able to specify the depth my script will work so
if the depth is 4, the script will look at all items from the root to 4
folders deep e.g

Something like Dir.glob([’’,’/’,’//’,’///’]) should do
without being too “manual”

Or if you like to change the depth:

def search_to_depth(n)
array = Array.new(n) {|i| ‘’ + '/’*i}
Dir.glob(array)
end

Cheers,

On 01/07/2010 09:17 PM, Stuart C. wrote:

Root
Folder 1
Folder 2
Folder 3

Any input is much appreciated.

You can use Find.prune for this. Try:

ruby19 -r find -e ‘Find.find("/usr/local"){|f| p f; Find.prune if
f.scan(%r{/}).size > 4}’

------------------------------------------------------------- Find#prune
prune()

  From Ruby 1.9.1

  Skips the current file or directory, restarting the loop with the
  next entry. If the current file is a directory, that directory 

will
not be recursively entered. Meaningful only within the block
associated with Find::find.

  See the +Find+ module documentation for an example.

Kind regards

robert

El Jueves, 7 de Enero de 2010, Stuart C. escribió:

Root
Folder 1
Folder 2
Folder 3

Any input is much appreciated.

I cannot imagine a “cool” way. Perhaps listing all the files in current
directory (File.dirname(__FILE)) and then inspecting each of them with
File.directory?(file). In case of “true” then inspect the content of
that
directory and repeat the operation (until depth is 4).

Yes, a bit manual though… :slight_smile:

About two months ago I adapted Find for my own purposes,
to automatically include the depth, and to have a “next” method
to make it easier to have two Finds working together.
(For comparing two directory structures, etc.)

I’ve put the code here, if you’re interested:
http://pastie.org/771204

What I’m still undecided on is the appropriate depth for a file!
For example:

root_file => depth == 0
root_dir => depth == 0
file => depth == 1 or 0 ? (I’m using 1 for now)
dir => depth == 1
file => depth == 2 or 1 ? (I’m using 1 for now)

The code I’m using for the depth is:

(1) at a root, setting the root depth as 0:
@depth = 0
@depth_adjuster = -( @root.count( “/” ) + @root.count( “\” ) )
if @root =~ /(?:(:|((\A|:)[/\]+))\z)/ then
@depth_adjuster += 1
@root_rem_sep = 0 # xx: / xx:/ etc
elsif k = ( @root =~ /(?:[/\]+\z)/ ) then
@depth_adjuster += 1
@root_rem_sep = k - @root.length # xx/ yy/xx/ etc
else
@root_rem_sep = 0 # xx yy/xx
end

(2) at a dir or file which is not a root:
@depth = pathv.count( “/” ) + pathv.count( “\” ) +
@depth_adjuster

[* Typo correction in the second file=> depth *]

What I’m still undecided on is the appropriate depth for a file! For
example:

root_file => depth == 0
root_dir => depth == 0
file => depth == 1 or 0 ? (I’m using 1 for now)
dir => depth == 1
file => depth == 2 or 1 ? (I’m using 2 for now)

I think this code will work best for me.

On another matter, is there an easier way to ignore files and just show
folders at present I am doing (not valid code)

if File.file?(path)

else
puts File.dirname(path)
end

Many thanks

Fleck Jean-Julien wrote:

Hello,

Basically I want to be able to specify the depth my script will work so
if the depth is 4, the script will look at all items from the root to 4
folders deep e.g

Something like Dir.glob([’’,’/’,’//’,’///’]) should do
without being too “manual”

Or if you like to change the depth:

def search_to_depth(n)
array = Array.new(n) {|i| ‘’ + '/’*i}
Dir.glob(array)
end

Cheers,

Hello,

def get_non_empty_dir_to_depth(n)
search_to_depth(n+1).collect{|f| File.dirname(f)}.uniq
end

Well, in fact, there is a much simpler way that does get empty
directories:

def get_dir_to_depth(n)
search_to_depth(n).select {|f| File.directory?(f)}
end

Cheers,

Hello Stuart,

2010/1/8 Stuart C. [email protected]:

I think this code will work best for me.

On another matter, is there an easier way to ignore files and just show
folders

If you just want the list of the folders from your recursion, you could
do

def search_to_depth(n)
array = Array.new(n) {|i| ‘’ + '/’*i}
Dir.glob(array)
end
=> nil
search_to_depth(2).collect{|f| File.dirname(f)}.uniq
=> [“.”, “Desktop”, “Documents”, “Downloads”, “Library”, “Movies”,
“Music”, “Photo Booth”, “Pictures”, “Public”, “Sites”]

Note that to get directories present at depth “n”, you need to expand
files until depth “n+1”, that is:

def get_non_empty_dir_to_depth(n)
search_to_depth(n+1).collect{|f| File.dirname(f)}.uniq
end

But this method doesn’t work if there isn’t any file in the directory
you are looking for (because we rely on the presence of at least one
file at the next level), I don’t know if it would matter in your
usage.

Cheers,

Thats for this, will give it a try

Fleck Jean-Julien wrote:

Hello,

def get_non_empty_dir_to_depth(n)
�search_to_depth(n+1).collect{|f| File.dirname(f)}.uniq
end

Well, in fact, there is a much simpler way that does get empty
directories:

def get_dir_to_depth(n)
search_to_depth(n).select {|f| File.directory?(f)}
end

Cheers,