Shane Williamson
Shane Williamson

Reputation: 1

File.rename throwing invalid argument error in Ruby script to rename all files in directory

I'm attempting to write a script that will take in a directory path to a folder, and rename all the files in that folder to a name plus a number. For instance, rename img_0936.JPG, img_0937.JPG to hockeyPic_001.JPG and hockeyPic_002.JPG.

So here's my script:

folder = '/Users/ShaneWilliamson/Desktop/cobalt pics'
newName = 'cobaltPic'

puts 'Renaming files...'
files = Dir.entries(folder).reject{|f| f[0] == '.'}
puts files

i = 1
files.each do |file|
  File.rename(file, newName + i.to_s + '.JPG')
  i += 1
end

It's currently returning the correct file names (before the rename) but throwing:

Renaming files...
.
..
.DS_Store
image1.JPG
image2.JPG
image3.JPG
image4.JPG
image5.JPG
IMG_1586.JPG
IMG_1587.JPG
fileNamer.rb:10:in `rename': Invalid argument - . or cobaltPic_001.JPG
(Errno::EINVAL)
from fileNamer.rb:10
from fileNamer.rb:9:in `each'
from fileNamer.rb:9
Shanes-MacBook-Air:Desktop ShaneWilliamson$ 

So it seems the reject method isn't doing quite what I expect, which I think could be causing the error (system won't let the script change the 'hidden' files?).

In case it's relevant, I'm running OSX 10.7.5 on a MacBook Air. Ruby version 1.8.7 per 'ruby -v' command, which I think is just what came on the system out of the box.

Upvotes: 0

Views: 1020

Answers (2)

Aetherus
Aetherus

Reputation: 8898

A quick and relatively safe way is to rename only those files whose names do NOT start with a dot. Those ".xxx" files are "hidden files" that are created typically by the operating system or some softwares, and they are not intended to be touched.

folder = '/Users/ShaneWilliamson/Desktop/cobalt pics'
newName = 'cobaltPic'

Dir.entries(folder).reject{|f| f[0] == '.'}.each_with_index(1) do |file, i|
  File.rename file, "#{newName}#{i}.JPG"
end

Upvotes: 1

user12341234
user12341234

Reputation: 7223

You might consider using an existing utility instead of writing your own. rename does just what you are trying to achieve and is available on most operating systems. Your whole script can be written as:

rename --just-print -N 001 's/.*/cobaltPic$N.jpg/' *.jpg

This command only shows you what the script would do, but doesn't actually rename anything. After you verify the output, you can remove the --just-print flag and it will apply the changes.

Upvotes: 0

Related Questions