Problem renaming files

Hi Everyone,

Im new to ruby and am having a hard time with something Im working on.

I want to write a script that takes file names as arguments, then uses
gets to get two values, and then renames the files based on those
values.

example:

I want to rename mulitple files, removing the build number, and
replacing it with another number.

engine.105 -> rename to engine.8

Anyways, so right now Im just working on doing this with one file at a
time. I realize this could be done without a script, but I want to end
up doing this with multiple files at once. My script is probably not the
most efficient way either, but I’d just like to know what Im doing wrong
with how Im doing it. Just so I can learn…

Below is the code… I run the file as:

ruby c.rb engine.105

I then enter the build number which is 105
Next I enter the version number I want to replace the build number with
which is 5

The following is what I get:

c.rb:14:in `rename’: No such file or directory - engine.5 or 5
(Errno::ENOENT)
from c.rb:14

=====================

#!/usr/bin/env ruby

Filename arguments

file_names = ARGV.dup.to_s

Have user input build number to be removed

puts “Please enter the build number you wish to be removed from the
file”
build_number = STDIN.gets.chomp.to_s

Have user input version number to be appended to file name

puts “Please enter the version number you wish to be appended”
version_number = STDIN.gets.chomp.to_s

Rename file replacing build number with version number

File.rename(file_names, file_names[build_number]= version_number)

puts “done!”

Jesús Gabriel y Galán wrote:

On Tue, May 11, 2010 at 5:10 AM, Jacob D. [email protected] wrote:

I want to rename mulitple files, removing the build number, and
Below is the code… I run the file as:
(Errno::ENOENT)

Have user input build number to be removed

puts “done!”

There are two problems here. The first one is that
file_names[build_number] = version will return the right hand side
expression, not the new value of the string, so you will be passing a
“5” to the rename method, not “engine.5”. The second is that by
calling []= on file_names you are changing the object referenced by
file_names, not making a new one, so you are passing “engine.5” as the
first argument to rename. Try this instead:

Rename file replacing build number with version number

new_name = file_names.dup
new_name[build_number] = version_number
File.rename(file_names, new_name)

Also, when you change things to receive multiple file names as
arguments to your script, you should probably change this line:

file_names = ARGV.dup.to_s

because that will join all the file names into a single string, which
is not what you want, I think.

Jesus.

Awesome! Yeap that worked! I see where I was making the mistakes last
night. I guess its good to step away from it for a bit everyonce in a
while.

So, I should remove the .to_s so that it will populate the multiple
names into an array correct?

Thanks!!!
Jacob

On Tue, May 11, 2010 at 5:10 AM, Jacob D. [email protected] wrote:

I want to rename mulitple files, removing the build number, and
Below is the code… I run the file as:
(Errno::ENOENT)

Have user input build number to be removed

puts “done!”

There are two problems here. The first one is that
file_names[build_number] = version will return the right hand side
expression, not the new value of the string, so you will be passing a
“5” to the rename method, not “engine.5”. The second is that by
calling []= on file_names you are changing the object referenced by
file_names, not making a new one, so you are passing “engine.5” as the
first argument to rename. Try this instead:

Rename file replacing build number with version number

new_name = file_names.dup
new_name[build_number] = version_number
File.rename(file_names, new_name)

Also, when you change things to receive multiple file names as
arguments to your script, you should probably change this line:

file_names = ARGV.dup.to_s

because that will join all the file names into a single string, which
is not what you want, I think.

Jesus.

On Tue, May 11, 2010 at 4:27 PM, Jacob D. [email protected] wrote:

file_names[build_number] = version will return the right hand side
File.rename(file_names, new_name)

Awesome! Yeap that worked! I see where I was making the mistakes last
night. I guess its good to step away from it for a bit everyonce in a
while.

So, I should remove the .to_s so that it will populate the multiple
names into an array correct?

Yes, if you do

file_names = ARGV.dup

you get an array of file names. Then you can iterate through that
array doing the operation to each of them:

Have user input build number to be removed

puts “Please enter the build number you wish to be removed from the
file”
build_number = STDIN.gets.chomp.to_s

Have user input version number to be appended to file name

puts “Please enter the version number you wish to be appended”
version_number = STDIN.gets.chomp.to_s

Rename each file replacing build number with version number

file_names.each do |file_name|
new_name = file_name.dup
new_name[build_number] = version_number
File.rename(file_name, new_name)
end

puts “done!”

something like that.

Jesus.

2010/5/11 Jesús Gabriel y Galán [email protected]:

On Tue, May 11, 2010 at 4:27 PM, Jacob D. [email protected] wrote:

Jesús Gabriel y Galán wrote:

On Tue, May 11, 2010 at 5:10 AM, Jacob D. [email protected] wrote:

So, I should remove the .to_s so that it will populate the multiple
names into an array correct?

Yes, if you do

file_names = ARGV.dup

you get an array of file names. Then you can iterate through that
array doing the operation to each of them:

You do not even need to #dup because ARGV is an Array already.

$ ruby19 -e ‘p ARGV.class’
Array

Have user input build number to be removed

puts “Please enter the build number you wish to be removed from the
file”
build_number = STDIN.gets.chomp.to_s

Have user input version number to be appended to file name

puts “Please enter the version number you wish to be appended”
version_number = STDIN.gets.chomp.to_s

#to_s is not needed but checking the input is probably also a good
idea. You could simply do

version_number = STDIN.gets.chomp
Integer(version_number) # will throw if not numeric

Kind regards

robert