[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Show newest file in directory?

Mmcolli00 Mom

12/18/2008 5:37:00 PM

If you have a directory full of files, how can you get the newest file
and oldest file from that directory?

require 'fileutils'
require 'find'
require 'ftools'
require 'enumerator'

Dir.entries("C:/New").each do |filename|
NewestFile = filename.max
OldestFile = filename.min
puts "newest"
puts NewestFile
puts "oldest"
puts OldestFile
end
--
Posted via http://www.ruby-....

6 Answers

Mark Thomas

12/18/2008 7:53:00 PM

0

On Dec 18, 12:36 pm, Mmcolli00 Mom <mmc_coll...@yahoo.com> wrote:
> If you have a directory full of files, how can you get the newest file
> and oldest file from that directory?

One way...

ages = Dir["C:/New"].map{|f| [f,File.mtime(f)] }.sort_by{|i|i[1]}

This gives you a sorted list of [filename,age] pairs. Then you can do
this:

newest, oldest = ages[0][0], ages[-1][0]


Or, if you want it in one fell swoop:

newest, oldest = Dir["C:/New"].map{|f| [f,File.mtime(f)] }.sort_by{|
i|i[1]}.map{|i| i[0]}.values_at(0,-1)

This is known as a "Swartzian Transform"

-- Mark.

Mmcolli00 Mom

12/18/2008 8:26:00 PM

0

Thanks Mark.
--
Posted via http://www.ruby-....

Robert Klemme

12/18/2008 10:47:00 PM

0

On 18.12.2008 20:52, Mark Thomas wrote:
> On Dec 18, 12:36 pm, Mmcolli00 Mom <mmc_coll...@yahoo.com> wrote:
>> If you have a directory full of files, how can you get the newest file
>> and oldest file from that directory?
>
> One way...
>
> ages = Dir["C:/New"].map{|f| [f,File.mtime(f)] }.sort_by{|i|i[1]}

IMHO that should read

ages = Dir.entries("C:/New").map{|f|
[f,File.mtime(File.join("C:/New",f))] }.sort_by{|i|i[1]}

But:

> Or, if you want it in one fell swoop:
>
> newest, oldest = Dir["C:/New"].map{|f| [f,File.mtime(f)] }.sort_by{|
> i|i[1]}.map{|i| i[0]}.values_at(0,-1)

We can do better, i.e. #map is superfluous

sorted = Dir.entries(dir).sort_by {|f| File.mtime(File.join(dir,f))}
puts sorted.first, sorted.last

Kind regards

robert


--
remember.guy do |as, often| as.you_can - without end

msnews.microsoft.com

12/19/2008 12:30:00 AM

0

Just a pet peeve.... but... Sorts are expensive and should be avoided
when possible. Finding min and max values are prime examples.

So...

newest = Dir.entries(dir).max {|a,b| (File.mtime(File.join(dir,a)) <=>
File.mtime(File.join(dir,b)))}


On Dec 18, 2008, at 5:42 PM, Robert Klemme wrote:

> On 18.12.2008 20:52, Mark Thomas wrote:
>> On Dec 18, 12:36 pm, Mmcolli00 Mom <mmc_coll...@yahoo.com> wrote:
>>> If you have a directory full of files, how can you get the newest
>>> file
>>> and oldest file from that directory?
>> One way...
>> ages = Dir["C:/New"].map{|f| [f,File.mtime(f)] }.sort_by{|i|i[1]}
>
> IMHO that should read
>
> ages = Dir.entries("C:/New").map{|f| [f,File.mtime(File.join("C:/
> New",f))] }.sort_by{|i|i[1]}
>
> But:
>
>> Or, if you want it in one fell swoop:
>> newest, oldest = Dir["C:/New"].map{|f| [f,File.mtime(f)] }.sort_by{|
>> i|i[1]}.map{|i| i[0]}.values_at(0,-1)
>
> We can do better, i.e. #map is superfluous
>
> sorted = Dir.entries(dir).sort_by {|f| File.mtime(File.join(dir,f))}
> puts sorted.first, sorted.last
>
> Kind regards
>
> robert
>
>
> --
> remember.guy do |as, often| as.you_can - without end
>


Mmcolli00 Mom

12/19/2008 2:48:00 AM

0

Thanks Everyone! Great advice!
--
Posted via http://www.ruby-....

Robert Klemme

12/19/2008 8:15:00 AM

0

2008/12/19 Mike Cargal <mike@cargal.net>:
> Just a pet peeve.... but... Sorts are expensive and should be avoided when
> possible. Finding min and max values are prime examples.
>
> So...
>
> newest = Dir.entries(dir).max {|a,b| (File.mtime(File.join(dir,a)) <=>
> File.mtime(File.join(dir,b)))}

While we're nitpicking... :-) In this case File.mtime is most likely
the most expensive operation as it does IO (or at least has to travel
into system call land). #max will invoke File.mtime multiple times for
the same file.

So, efficiency wise an explicit one pass solution is probably best:

max = Time.at 0
file = nil

Dir.open(dir) do |d|
d.each do |f|
mt = File.mtime(File.join(dir, f))
if mt > max
max = mt
file = f
end
end
end

puts file

Btw, there is another nice short solution, which unfortunately also
suffers the multiple #mtime per File issue (you can easily see this by
placing "p f;" before the "File.mtime" in the block):

puts Dir.open(dir) {|d| d.max_by {|f| File.mtime(File.join(dir, f))}}

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end