Renaming files randomly

Got this request yesterday and still haven't had
time to decipher it and code it -- I figured I'd
throw it out here and see what you folks come up with:

Eric wrote:
>
> I want to change the names of several hundred files to random numbers
> (without overwriting any files). I have a bunch of pictures for our
> reception, but they're basically in chronological order by their current
> filenames. But I want the slideshow to play in random order, so I need to
> randomize the filenames.

I'll also ask why the slideshow software can't just be
told to show things randomly...

Thanks,

···

--
Bil
http://fun3d.larc.nasa.gov

Hi --

Got this request yesterday and still haven't had
time to decipher it and code it -- I figured I'd
throw it out here and see what you folks come up with:

Eric wrote:

I want to change the names of several hundred files to random numbers
(without overwriting any files). I have a bunch of pictures for our
reception, but they're basically in chronological order by their current
filenames. But I want the slideshow to play in random order, so I need to
randomize the filenames.

I'll also ask why the slideshow software can't just be
told to show things randomly...

Dir["photos/*"].sort_by { rand }

If the renaming is really necessary, then something like:

   Dir.chdir("photos") do
     files = Dir["*"]
     new_names = [*0...files.size].sort_by { rand }
     files.zip(new_names).each do |f,n|
       File.rename(f, n.to_s)
     end
   end

They may not get shown in numerical order, because of how directories
get sorted, but it shouldn't matter because they'll be in random order
anyway.

David

···

On Mon, 10 Jul 2006, Bil Kleb wrote:

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS, the Ruby book for
                                                     Rails developers
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

rather than rename, i'd just make a dir full of links:

   harp:~ > cat a.rb
   require 'fileutils'

   dir, dir_full_of_links, ignored = ARGV

   dir_full_of_links ||= dir + '.d.links'
   d, f, fu = Dir, File, FileUtils

   glob = f.join dir, '*'
   srcs = d.glob(glob).map{|path| f.expand_path path}

   link = 'a'
   dsts = srcs.map{|path| f.join dir_full_of_links, link.succ!}

   fu.rm_rf dir_full_of_links
   fu.mkdir_p dir_full_of_links
   dsts.sort_by{ rand }

   srcs.zip(dsts) do |src, dst|
     puts "#{ src } -->> #{ dst }"
     fu.ln_s src, dst
   end

   harp:~ > ls -ltar tmp
   total 716
   -rw-rw-r-- 1 ahoward ahoward 393 May 5 05:30 G2006050506.sfctmp.dat.hdr
   -rw-rw-r-- 1 ahoward ahoward 393 May 5 11:30 G2006050512.sfctmp.dat.hdr
   -rw-rw-r-- 1 ahoward ahoward 260640 May 5 11:30 G2006050512.sfctmp.dat
   -rw-rw-r-- 1 ahoward ahoward 393 May 5 17:30 G2006050518.sfctmp.dat.hdr
   -rw-rw-r-- 1 ahoward ahoward 260640 May 5 17:30 G2006050518.sfctmp.dat
   -rw-rw-r-- 1 ahoward ahoward 90112 May 23 09:30 G2006050506.sfctmp.dat
   drwxrwxr-x 2 ahoward ahoward 8192 Jul 9 09:25 .
   drwx------ 170 ahoward ahoward 81920 Jul 9 09:26 ..

   harp:~ > ruby a.rb tmp
   /home/ahoward/tmp/G2006050506.sfctmp.dat -->> tmp.d.links/b
   /home/ahoward/tmp/G2006050506.sfctmp.dat.hdr -->> tmp.d.links/c
   /home/ahoward/tmp/G2006050512.sfctmp.dat -->> tmp.d.links/d
   /home/ahoward/tmp/G2006050512.sfctmp.dat.hdr -->> tmp.d.links/e
   /home/ahoward/tmp/G2006050518.sfctmp.dat -->> tmp.d.links/f
   /home/ahoward/tmp/G2006050518.sfctmp.dat.hdr -->> tmp.d.links/g

   harp:~ > ls -ltar tmp.d.links/
   total 88
   lrwxrwxrwx 1 ahoward ahoward 44 Jul 9 09:26 g -> /home/ahoward/tmp/G2006050518.sfctmp.dat.hdr
   lrwxrwxrwx 1 ahoward ahoward 40 Jul 9 09:26 f -> /home/ahoward/tmp/G2006050518.sfctmp.dat
   lrwxrwxrwx 1 ahoward ahoward 44 Jul 9 09:26 e -> /home/ahoward/tmp/G2006050512.sfctmp.dat.hdr
   lrwxrwxrwx 1 ahoward ahoward 40 Jul 9 09:26 d -> /home/ahoward/tmp/G2006050512.sfctmp.dat
   lrwxrwxrwx 1 ahoward ahoward 44 Jul 9 09:26 c -> /home/ahoward/tmp/G2006050506.sfctmp.dat.hdr
   lrwxrwxrwx 1 ahoward ahoward 40 Jul 9 09:26 b -> /home/ahoward/tmp/G2006050506.sfctmp.dat
   drwx------ 171 ahoward ahoward 81920 Jul 9 09:26 ..
   drwxrwxr-x 2 ahoward ahoward 4096 Jul 9 09:26 .

regards.

-a

···

On Mon, 10 Jul 2006, Bil Kleb wrote:

Got this request yesterday and still haven't had
time to decipher it and code it -- I figured I'd
throw it out here and see what you folks come up with:

Eric wrote:

I want to change the names of several hundred files to random numbers
(without overwriting any files). I have a bunch of pictures for our
reception, but they're basically in chronological order by their current
filenames. But I want the slideshow to play in random order, so I need to
randomize the filenames.

I'll also ask why the slideshow software can't just be
told to show things randomly...

Thanks,

--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

this loop loses data

if

   files = %w( a b c )

and

   new_names = %w( c b a )

then the renaming order is

   a -->> c
   b -->> b
   c -->> a

so

   File.rename 'a', 'c' # c is clobbered
   File.rename 'b', 'b' # ok
   File.rename 'c', 'a' # a is clobbered, new c is lost

at the end of the loop you'll have only files 'a' and 'b' and no error will
have been thrown.

regards.

-a

···

On Mon, 10 Jul 2006 dblack@wobblini.net wrote:

Dir["photos/*"].sort_by { rand }

If the renaming is really necessary, then something like:

Dir.chdir("photos") do
   files = Dir["*"]
   new_names = [*0...files.size].sort_by { rand }
   files.zip(new_names).each do |f,n|
     File.rename(f, n.to_s)
   end
end

--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

dblack@wobblini.net wrote:

  Dir.chdir("photos") do
    files = Dir["*"]
    new_names = [*0...files.size].sort_by { rand }
    files.zip(new_names).each do |f,n|
      File.rename(f, n.to_s)
    end
  end

Thanks David.

I'll push that over and see what comes back.

Also, thanks for showing "zip" in action -- I just
learned about that one a couple months ago and hadn't
figured out a place to use it yet.

Regards,

···

--
Bil
http://fun3d.larc.nasa.gov

sorry - replace 'a b c' with '1 2 3' and 'c b a' with '3 2 1' - basically you
lose data when the slides have numbered names to begin with, which i noticed
because this is exactly how my slideshow software names it's slides! :wink:

-a

···

On Mon, 10 Jul 2006 Ara.T.Howard@noaa.gov wrote:

this loop loses data

if

files = %w( a b c )

and

new_names = %w( c b a )

then the renaming order is

a -->> c
b -->> b
c -->> a

so

File.rename 'a', 'c' # c is clobbered
File.rename 'b', 'b' # ok
File.rename 'c', 'a' # a is clobbered, new c is lost

at the end of the loop you'll have only files 'a' and 'b' and no error will
have been thrown.

--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

Hey,

You could rewrite without the zip and the temporary variable...
ala:

Dir.chdir("photos") do
  Dir["*"].sort_by{rand}.each_with_index do |f,n|
    File.rename(f, n.to_s)
  end
end

Though be careful, you've just lost the file-name extension, and
unpretty things could happen if you run the script over the same
directory multiple times (which I guess could happen when you want to
re-shuffle the playlist).

Regards,

Tris

>
> Dir.chdir("photos") do
> files = Dir["*"]
> new_names = [*0...files.size].sort_by { rand }
> files.zip(new_names).each do |f,n|
> File.rename(f, n.to_s)
> end
> end

Thanks David.

I'll push that over and see what comes back.

Also, thanks for showing "zip" in action -- I just
learned about that one a couple months ago and hadn't
figured out a place to use it yet.

One useful use of zip is transformation two arrays into hash pairs:

  > Hash[*%w(a b c d).zip([1, 2, 3, 4]).flatten]
  => {"a"=>1, "b"=>2, "c"=>3, "d"=>4}

marcel

···

On Mon, Jul 10, 2006 at 01:05:06AM +0900, Bil Kleb wrote:

dblack@wobblini.net wrote:

--
Marcel Molina Jr. <marcel@vernix.org>

Hi --

···

On Mon, 10 Jul 2006, ara.t.howard@noaa.gov wrote:

On Mon, 10 Jul 2006 Ara.T.Howard@noaa.gov wrote:

this loop loses data

if

files = %w( a b c )

and

new_names = %w( c b a )

then the renaming order is

a -->> c
b -->> b
c -->> a

so

File.rename 'a', 'c' # c is clobbered
File.rename 'b', 'b' # ok
File.rename 'c', 'a' # a is clobbered, new c is lost

at the end of the loop you'll have only files 'a' and 'b' and no error will
have been thrown.

sorry - replace 'a b c' with '1 2 3' and 'c b a' with '3 2 1' - basically you
lose data when the slides have numbered names to begin with, which i noticed
because this is exactly how my slideshow software names it's slides! :wink:

OK, then:

   new_names = [*0...files.size].map {|n| "MUNGED#{n}" }.sort_by { rand }

:slight_smile:

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS, the Ruby book for
                                                     Rails developers
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me