Find.find, limited recursion..

B

Brian Wallace

[Note: parts of this message were removed to make it a legal post.]

Hi all,

I'm working on a script that's currently using Find.find to process a
complete directory tree of files and directories .. .however I needed
specific behavior, and I'm still fairly new to this...

Basically it works like this, the user specifies the root directory of a
collection of sub-directories we are interested in .. for instance:

User specifies: C:\Root

C:\Root
|
-->\Dir1
|
-->Files_in_dir1
|
-->\Dir2
|
-->Files_in_dir2


But we are only interested in the _files_ in \Dir1 , \Dir2 ..and want to
essentially Prune recursion into C:\Root\Dir1\Subdir_of_Dir1 , and
C:\Root\Dir2\Subdir_of_Dir2 if those exist ..

This is what I am currently using, however it will pick up the sub
directories of Dir1 and Dir2 and update the hash... Does anyone see any way
this could be refactored to not update the "process_list" hash with the sub
directories of Dir1 and Dir2?

--

@root_dir = "C:\Root"

process_list = Hash.new {|h,k| h[k] = []}

Find.find(@root_dir.to_s) do |f|
f = f.gsub(/\\/,'/')
next if File.stat(f).directory? or f.include?('skipped_filename')
Find.prune if f.include?("skipped_dirname")
d, b = File.split(f)
process_list [d] << b
end

Thanks in advance!

Brian
 
D

Daniel Berger

Brian said:
Hi all,

I'm working on a script that's currently using Find.find to process a
complete directory tree of files and directories .. .however I needed
specific behavior, and I'm still fairly new to this...

Basically it works like this, the user specifies the root directory of a
collection of sub-directories we are interested in .. for instance:

User specifies: C:\Root

C:\Root
|
-->\Dir1
|
-->Files_in_dir1
|
-->\Dir2
|
-->Files_in_dir2


But we are only interested in the _files_ in \Dir1 , \Dir2 ..and want to
essentially Prune recursion into C:\Root\Dir1\Subdir_of_Dir1 , and
C:\Root\Dir2\Subdir_of_Dir2 if those exist ..

This is what I am currently using, however it will pick up the sub
directories of Dir1 and Dir2 and update the hash... Does anyone see any way
this could be refactored to not update the "process_list" hash with the sub
directories of Dir1 and Dir2?

--

@root_dir = "C:\Root"

process_list = Hash.new {|h,k| h[k] = []}

Find.find(@root_dir.to_s) do |f|
f = f.gsub(/\\/,'/')
next if File.stat(f).directory? or f.include?('skipped_filename')
Find.prune if f.include?("skipped_dirname")
d, b = File.split(f)
process_list [d] << b
end

Thanks in advance!

Brian

Perhaps you would like file-find better. I think this is what you want:

gem install file-find

rule = File::Find.new(
:path => ['C:/Root/Dir1', 'C:/Root/Dir2'],
:maxdepth => 2,
:directory? => false
)

p rule.find

http://shards.rubyforge.org/wiki/wiki.pl?File-Find

Regards,

Dan
 
R

Robert Klemme

2009/9/15 Brian Wallace said:
Hi all,

=A0I'm working on a script that's currently using Find.find to process a
complete directory tree of files and directories .. .however I needed
specific behavior, and I'm still fairly new to this...

Basically it works like this, the user specifies the root directory of a
collection of sub-directories we are interested in .. for instance:

User specifies: C:\Root

C:\Root
=A0 =A0 =A0 =A0 =A0|
=A0 =A0 =A0 =A0 =A0-->\Dir1
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -->Files_in_dir1
=A0 =A0 =A0 =A0 =A0|
=A0 =A0 =A0 =A0 =A0-->\Dir2
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -->Files_in_dir2


But we are only interested in the _files_ in \Dir1 , \Dir2 =A0..and want = to
essentially Prune recursion into C:\Root\Dir1\Subdir_of_Dir1 , and
C:\Root\Dir2\Subdir_of_Dir2 if those exist ..

This is what I am currently using, however it will pick up the sub
directories of Dir1 and Dir2 and update the hash... Does anyone see any w= ay
this could be refactored to not update the "process_list" hash with the s= ub
directories of Dir1 and Dir2?

--

@root_dir =3D "C:\Root"

process_list =3D Hash.new {|h,k| h[k] =3D []}

Find.find(@root_dir.to_s) do |f|
=A0f =3D f.gsub(/\\/,'/')
=A0next if File.stat(f).directory? or f.include?('skipped_filename')
=A0Find.prune if f.include?("skipped_dirname")
=A0 d, b =3D File.split(f)
=A0process_list [d] << b
end

Thanks in advance!

require 'no gems' # silly joke

Dir["#{@root_dir}/*/*"].each do |f|
next unless File.file? f
d, b =3D File.split f
process_list[d] << b
end

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
B

Brian Wallace

[Note: parts of this message were removed to make it a legal post.]

Thanks Dan,

That would actually work out OK - however since i'm using JRuby I wouldn't
be able to use a gem with native C extensions..

Thanks for the suggestion!

Brian

Brian said:
Hi all,

I'm working on a script that's currently using Find.find to process a
complete directory tree of files and directories .. .however I needed
specific behavior, and I'm still fairly new to this...

Basically it works like this, the user specifies the root directory of a
collection of sub-directories we are interested in .. for instance:

User specifies: C:\Root

C:\Root
|
-->\Dir1
|
-->Files_in_dir1
|
-->\Dir2
|
-->Files_in_dir2


But we are only interested in the _files_ in \Dir1 , \Dir2 ..and want to
essentially Prune recursion into C:\Root\Dir1\Subdir_of_Dir1 , and
C:\Root\Dir2\Subdir_of_Dir2 if those exist ..

This is what I am currently using, however it will pick up the sub
directories of Dir1 and Dir2 and update the hash... Does anyone see any
way
this could be refactored to not update the "process_list" hash with the
sub
directories of Dir1 and Dir2?

--

@root_dir = "C:\Root"

process_list = Hash.new {|h,k| h[k] = []}

Find.find(@root_dir.to_s) do |f|
f = f.gsub(/\\/,'/')
next if File.stat(f).directory? or f.include?('skipped_filename')
Find.prune if f.include?("skipped_dirname")
d, b = File.split(f)
process_list [d] << b
end

Thanks in advance!

Brian
Perhaps you would like file-find better. I think this is what you want:

gem install file-find

rule = File::Find.new(
:path => ['C:/Root/Dir1', 'C:/Root/Dir2'],
:maxdepth => 2,
:directory? => false
)

p rule.find

http://shards.rubyforge.org/wiki/wiki.pl?File-Find

Regards,

Dan
 
B

Brian Wallace

[Note: parts of this message were removed to make it a legal post.]

Robert,

Hrrm - A simple solution of course ... and I've spent all this time trying
to figure it out on my own , without asking for help! :)

You've helped me in the past with a few other problems, and you were spot on
each time ..

I envy you, and hope that I am able to become even as half as knowledgeable
as you are..

Best Regards,

Brian

2009/9/15 Brian Wallace said:
Hi all,

I'm working on a script that's currently using Find.find to process a
complete directory tree of files and directories .. .however I needed
specific behavior, and I'm still fairly new to this...

Basically it works like this, the user specifies the root directory of a
collection of sub-directories we are interested in .. for instance:

User specifies: C:\Root

C:\Root
|
-->\Dir1
|
-->Files_in_dir1
|
-->\Dir2
|
-->Files_in_dir2


But we are only interested in the _files_ in \Dir1 , \Dir2 ..and want to
essentially Prune recursion into C:\Root\Dir1\Subdir_of_Dir1 , and
C:\Root\Dir2\Subdir_of_Dir2 if those exist ..

This is what I am currently using, however it will pick up the sub
directories of Dir1 and Dir2 and update the hash... Does anyone see any way
this could be refactored to not update the "process_list" hash with the sub
directories of Dir1 and Dir2?

--

@root_dir = "C:\Root"

process_list = Hash.new {|h,k| h[k] = []}

Find.find(@root_dir.to_s) do |f|
f = f.gsub(/\\/,'/')
next if File.stat(f).directory? or f.include?('skipped_filename')
Find.prune if f.include?("skipped_dirname")
d, b = File.split(f)
process_list [d] << b
end

Thanks in advance!

require 'no gems' # silly joke

Dir["#{@root_dir}/*/*"].each do |f|
next unless File.file? f
d, b = File.split f
process_list[d] << b
end

Kind regards

robert
 
D

Daniel Berger

Thanks Dan,

=A0That would actually work out OK - however since i'm using JRuby I woul= dn't
be able to use a gem with native C extensions..

Thanks for the suggestion!

There's a JRuby specific gem for file-find. A simple "gem install file-
find" should work, but if it doesn't try "gem install file-find --
platform=3Djava" and see if that works.

Regards,

Dan
 
B

Bertram Scharpf

Hi,

Am Mittwoch, 16. Sep 2009, 06:01:48 +0900 schrieb Brian Wallace:
I'm working on a script that's currently using Find.find to process a
complete directory tree of files and directories .. .however I needed
specific behavior, and I'm still fairly new to this...

This is what I am currently using, however it will pick up the sub
directories of Dir1 and Dir2 and update the hash... Does anyone see any way
this could be refactored to not update the "process_list" hash with the sub
directories of Dir1 and Dir2?

--

@root_dir = "C:\Root"

process_list = Hash.new {|h,k| h[k] = []}

Find.find(@root_dir.to_s) do |f|
f = f.gsub(/\\/,'/')
next if File.stat(f).directory? or f.include?('skipped_filename')
Find.prune if f.include?("skipped_dirname")
d, b = File.split(f)
process_list [d] << b
end

Of course I recommend my RbFind tool. It is pure Ruby, no C to
compile.

<http://raa.ruby-lang.org/project/rbfind>

Do something like (untested):

process_list = Hash.new { |h,k| h[k] = [] }

RbFind.run root do
prune if dir?
next if name =~ /skipped/
process_list[ dirname] << name
end

Bertram
 
R

Robert Klemme

Hrrm - A simple solution of course ... and I've spent all this time trying
to figure it out on my own , without asking for help! :)
:)

You've helped me in the past with a few other problems, and you were spot on
each time ..

Great to hear that I could provide helpful insights.
I envy you, and hope that I am able to become even as half as knowledgeable
as you are..

You sure will - you practically cannot avoid it: experience takes time -
and it automatically comes with time. :)

Btw, it's the mistakes we learn from.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top