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,

Hi –

On Mon, 10 Jul 2006, Bil K. wrote:

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 K. wrote:

randomize the filenames.

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

On Mon, 10 Jul 2006 [email protected] wrote:

then the renaming order is

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:

-a

On Mon, 10 Jul 2006 [email protected] wrote:

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

[email protected] 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,

Hi –

On Mon, 10 Jul 2006, [email protected] wrote:

new_names = %w( c b a )
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

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

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

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