From: Stefano Crocco Date: 2007-03-15T02:42:59+09:00 Subject: Re: Copying files and changing their names Alle mercoled狸 14 marzo 2007, Sam Fent ha scritto: > Stefano Crocco wrote: > > NOT TESTED - make a trial with some useless directory before using it on > > real > > data > > Hi Stefano (anzi, 'ciao!'), > > Thank you very much -- that has helped me tremendously. I have one > further question though. What if, instead of the number "9", I wanted to > copy the file with the HIGHEST number. > > For example, my files might be > > example1.txt > example2.txt > test1.txt > test2.txt > test3.txt > > If I wanted to change example2.txt to example-final.txt, and test3.txt > to test-final.txt, how could I iterate throught the files to find the > file with the highest number? > > Grazie mille per qualsiasi aiuto, > Sam This should work: require 'find' require 'set' require 'file_utils' Find.find('.') do |f| # consider only directories, we'll take care of files later if File.directory?(f) # create a Set containing the names of the files in the directory f [1] entries=Set.new(Dir.entries(f).reject{|e| File.directory?(e)}) #separate the files basing on their basename (the part before -number) [2] names=entries.classify{|e| e.match(/^.*-\d+$/)[1]} # for each of the basenames names.each_value do |v| # sort the set basing on the number and select the last name=v.sort_by{|n| n.match(/-(\d+)/)[1].to_i}.last # copy it to the new name. name is relative to f, so we prepend it FileUtils.cp "#{f}#{name}", "#{f}#{name.sub(/-\d+$/, '-final')}" end end end The line marked by [2] creates a hash of sets, each of them containing the files with the same basename. This method is the only reason to use a set in line [1], instead of keeping the array. For instance, if the directory f contains the files a-1 a-2 a-3 b-1 b-2 c-1 c-2 c-3 c-4 the result of line [2] will be a hash with keys 'a', 'b' and 'c'. The keys 'a' will contain a set with elements 'a-1', 'a-2', 'a-3', and so on for the other keys. Stefano