1

i have a file that looks like this:

TTITLE0=track name 1
TTITLE1=track name 2

and a directory that contains track01.cdda.wav.mp3 and track02.cdda.wav.mp3

i have the following code, which creates 2 different arrays, 1 with the track names and 1 with the track titles:

tracks = Dir.glob("*.mp3")

tracknames = Array.new
File.open('read').each do |line|
  if line =~ /TTITLE/
    tracknames << line.split("=")[1].strip!
  end
end

this gives me 2 arrays:

["track name 1", "track name 2"]

and

["track01.cdda.wav.mp3", "track02.cdda.wav.mp3"]

i would like to rename the files in the second array with the elements of the first array. so, "track01.cdda.wav.mp3" would become "track name 1.mp3".

here is what i have tried so far:

tracks.map {|track| File.rename("#{tracks}", "#{tracknames}.mp3") }

and i get the error:

No such file or directory - track01.cdda.wav.mp3track02.cdda.wav.mp3 or track name 1track name 2 (Errno::ENOENT)

i have to keep in mind that in the future there could be any number of elements in each array, but the numbers will be equal to each other.

any ideas?

1
  • anyone like to explain why this got downvoted? Commented Jul 4, 2011 at 6:57

2 Answers 2

4

Use Array#zip:

tracks.zip(tracknames).each do |track, trackname|
  File.rename track, "#{trackname}.mp3"
end

Alternatively (less fun, but doesn't create an intermediary array of arrays prior to enumeration):

tracks.each_with_index do |track, i|
  File.rename track, "#{tracknames[i]}.mp3"
end
Sign up to request clarification or add additional context in comments.

2 Comments

awesome, 1st one worked for me no issue. what if i wanted to add a number to the beginning of the track number? could i use the second example and File.rename track, "#[i] #{tracknames[i]}.mp3"?
You could use the second technique like that, yes, or you could: tracks.zip(tracknames).each_with_index{ |(track, trackname), i| ... }
2

Do you really need to have two arrays? You could get by with just one:

tracks = Dir.glob("*.mp3")
File.open('read').each do |line|
  if line =~ /TTITLE/
    to = line.split("=")[1].strip!
    File.rename tracks.shift, "#{to}.mp3"
  end
end

And then end of that, your shift calls will have left tracks empty but that may not be a problem.

As far as your:

tracks.map {|track| File.rename("#{tracks}", "#{tracknames}.mp3") }

approach goes, the problem is that you're calling to_s on the tracks array when you interpolate it as "#{tracks}" and that just mashes all the individual strings in tracks together as one big pile of "not what you want". Similarly for tracknames. And map isn't what you want as you're not doing anything with the File.rename return values. However, you could do this:

tracks.each {|track| File.rename("#{track}", "#{tracknames.shift}.mp3") }

Or use each_with_index:

tracks.each_with_index {|track,i| File.rename("#{track}", "#{tracknames[i]}.mp3") }

That one would leave tracknames intact.

2 Comments

i had thought about that, but couldn't get it to work. this just takes care of the renaming as soon as it finds an eligible line to rename it with. cool.
@rick: That's called "true laziness" which, unlike "false laziness", is a good thing. Except when it isn't.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.