renaming files randomly

B

Bil Kleb

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:
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,
 
D

dblack

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:


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

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
http://www.manning.com/black => RUBY FOR RAILS, the Ruby book for
Rails developers
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
(e-mail address removed) => me
 
A

ara.t.howard

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:


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

Thanks,

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
 
A

ara.t.howard

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

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
 
A

ara.t.howard

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! ;-)

-a
 
D

dblack

Hi --

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! ;-)

OK, then:

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

:)


David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
http://www.manning.com/black => RUBY FOR RAILS, the Ruby book for
Rails developers
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
(e-mail address removed) => me
 
B

Bil Kleb

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,
 
T

ToRA

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
 

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,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top