Newb Wants to Better His File, Dir code


#1

I’ve got code working to do what I want but I’m hoping there is a
better way. Mine seems clumsy.

My goal is to search over all files, identify all that are directories
and then do something to each directory. I don’t need to go into
directories recursively yet.

The fact that Dir.foreach returns strings seems odd to me. All advice
appreciated.

#!/usr/local/bin/ruby

dpath = Dir.getwd

Dir.foreach(dpath) do
|x|
ddir = File.join(dpath,x)
if File.directory?(ddir) && x != “.” && x != “…” then
puts %x{du -sh #{x}}
end
end


#2

On Jun 8, 7:31 pm, R. B. Love removed_email_address@domain.invalid wrote:

#!/usr/local/bin/ruby

dpath = Dir.getwd

Dir.foreach(dpath) do
|x|
ddir = File.join(dpath,x)
if File.directory?(ddir) && x != “.” && x != “…” then
puts %x{du -sh #{x}}
end
end

One way simplify your handling of files and directories is to use Rio.
This will require you to install a module that is not a part of the
standard Ruby distribution. The easiest way to do this is:
gem install rio
(or on Unix or Linux: sudo gem install rio)

Then your code can be reduced to:

require ‘rio’

rio.dirs do |x|
puts %x{du -sh #{x}}
end


#3

On Sat, 2007-09-06 at 11:35 +0900, R.B.Love wrote:

end
Try:

    dirs = Dir.entries(".").reject{|e| /\.{1,2}/ =~ e}.find_all{|e|
    File.directory? e}

At this point you have a list of directory names. You can do whatever
you like to that list using .each(), .inject(), .collect(), etc.


#4

Michael T. Richter wrote:

appreciated.
puts %x{du -sh #{x}}

At this point you have a list of directory names. You can do whatever
you like to that list using .each(), .inject(), .collect(), etc.

The above has a small bug: it rejects all hidden directories. If you
want to block only “…” and “.”, then change it to:

dirs = Dir.entries(".").reject{|e| /.{1,2}$/ =~ e}.find_all{|e|
File.directory? e}


#5

On Jun 8, 8:42 pm, Dan Z. removed_email_address@domain.invalid wrote:

The fact that Dir.foreach returns strings seems odd to me. All advice
puts %x{du -sh #{x}}

The above has a small bug: it rejects all hidden directories. If you
want to block only “…” and “.”, then change it to:

    dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
            File.directory? e}

This also has bug if you have a file name ‘abc.’

Use rio.


#6

On Sat, 2007-09-06 at 12:42 +0900, Dan Z. wrote:

    dirs = Dir.entries(".").reject{|e| /\.{1,2}/ =~ e}.find_all{|e|
    File.directory? e}

The above has a small bug: it rejects all hidden directories. If you
want to block only “…” and “.”, then change it to:

dirs = Dir.entries(".").reject{|e| /.{1,2}$/ =~ e}.find_all{|e|
File.directory? e}

Ah. That is true. I tested it in a directory that didn’t have hidden
files or directories, so didn’t note that.


#7

On Sat, 2007-09-06 at 13:00 +0900, rio4ruby wrote:

    dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
            File.directory? e}

This also has bug if you have a file name ‘abc.’

There’s bugs in most (all?) off-the-cuff code put up in mailing lists to
illustrate a point. Yours (and the OP’s) had the bug of not working on
directories with spaces in the name.

Use rio.

http://snakeratpig.blogspot.com/2007/06/functional-pollution.html


#8

On Jun 8, 8:42 pm, Dan Z. removed_email_address@domain.invalid wrote:

Michael T. Richter wrote:

On Sat, 2007-09-06 at 11:35 +0900, R.B.Love wrote:

I’ve got code working to do what I want but I’m hoping there is a
better way. Mine seems clumsy.

My goal is to search over all files, identify all that are directories
and then do something to each directory. I don’t need to go into
directories recursively yet.

<snip OP’s code>

    dirs = Dir.entries(".").reject{|e| /\.{1,2}$/ =~ e}.find_all{|e|
            File.directory? e}

If hidden directories are not important, maybe try:

[sshaw@localhost ~]$ ls -a
. .emacs.d .ICEauthority
.openoffice.org2.0
… .esd_auth images .recently-used
addr.pl .evolution java ruby

ruby -le’Dir["/home/sshaw/*/"].each { |d| print d }’
/home/sshaw/video/
/home/sshaw/me/
/home/sshaw/ruby/
/home/sshaw/java/
/home/sshaw/dos-mundos/
/home/sshaw/cti/
/home/sshaw/wb/
/home/sshaw/images/
/home/sshaw/music/
/home/sshaw/Desktop/
/home/sshaw/GDMX/
/home/sshaw/mysql/


#9

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi rbLove,

another solution is to delete the array items beforehand:

class Dir
def self.dir_entries path, rejects = [ ‘.’, ‘…’ ]
( Dir.entries( path ) - rejects ).select { |entry|
File.directory? entry }
end
end

=begin
irb(main):021:0> Dir.chdir ‘/tmp’
=> 0
irb(main):022:0> Dir.dir_entries ‘.’
=> [".X11-unix", “501”]
irb(main):023:0> Dir.dir_entries ‘.’, []
=> [".", “…”, “.X11-unix”, “501”]
irb(main):024:0>
=end

This is the code I’m still using…

Sincereley
Florian

Am 09.06.2007 um 06:36 schrieb Michael T. Richter:

http://snakeratpig.blogspot.com/2007/06/functional-pollution.html


Michael T. Richter removed_email_address@domain.invalid (GoogleTalk:
removed_email_address@domain.invalid)
A well-designed and humane interface does not need to be split into
beginner and expert subsystems. (Jef Raskin)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFGaldNl1R1ZNDW4WgRApPPAJ4/FVGxK7LXapjCAySUk7/FoyGP0QCfY6O2
a0a5NEcSS/etT88QZam2zHM=
=ImGP
-----END PGP SIGNATURE-----


#10

rio4ruby wrote:

#!/usr/local/bin/ruby
File.directory? e}
Use rio.

RIO is a great library. It is also a huge library to load for one simple
task. Though it has bugs in it, the author didn’t claim that it was the
total solution nor that it didn’t leave any holes - but the initial
comment from BB didn’t ask for this - BB asked if the original code
worked or was “ugly”.

Oh - and hats off to BB. A new person asking for advice on whether their
code is ugly is to be applauded.

What we would need to know is whether BB want to learn the best Ruby way
to do the directory search, or whether they want to do this as a
component in a much larger file processing application. If its the
former, then going with the pure Ruby code is good - and efficient. If
its the latter then RIO is an answer.

For me, the above solution would seem to be more in keeping with “The
Ruby Way”.


#11

On 2007-06-08 20:55:42 -0700, rio4ruby removed_email_address@domain.invalid
said:

File.directory? e}

This also has bug if you have a file name ‘abc.’

Use rio.

Wouldn’t changing the regex to read /^.{1,2}$/ fix this problem?

Seems like a lot of unnecessary effort to complicate this code up with
an extra library to fix a regular expression.

-Erik