views:

383

answers:

8

I have several hundred *.mp3 files in c:\files. There are all imaginable filenames in there like

  • milad.mp3 (good behaving)
  • hey you.mp3 (space in filename)
  • systemofadown.mp3 (long filename)
  • howdy(1).mp3 (parentheses in filename)

and any combination of the last three conditions. I want to rename the files to 001-test.mp3, 002-mp3, ... It doesn't matter which file gets which name. have written a batch file to do the rename. Here is my code (with line numbers added):

01  rem @echo off
02  cls
03  set _number=%1
04  lfnfor on
05
06  :F1TO10
07  IF NOT EXIST *.mp3. goto end
08  if %_number% gtr 9 goto F10TO100
09  for /f %%a IN ('dir /b *.mp3') do rename %%~na.mp3 00%_number%-test.mp4
10  set /a _number +=1
11  goto F1TO10
12
13  :F10TO100
14  IF NOT EXIST *.mp3. goto end
15  if %_number% gtr 99 goto F100TO1000
16  for /f %%a IN ('dir /b *.mp3') do rename %%~na.mp3 0%_number%-test.mp4
17  set /a _number +=1
18  goto F10TO100
19
20  :F100TO1000
21  IF NOT EXIST *.mp3. goto end
22  if %_number% gtr 999 goto end
23  for /f %%a IN ('dir /b *.mp3') do rename %%~na.mp3 %_number%-test.mp4
24  set /a _number +=1
25  goto F100TO1000
26
27  :end
28  for /f %%a IN ('dir /b *.mp4') do rename %%~na.mp4 %%~na.mp3
29  echo Done

This code works fine for good behaving filenames (i.e. no spaces, no parentheses, no longer than 8 chars long). But if I have even a single file with a bad behaving filename, the script breaks (it loops endlessly until I stop it with Ctrl-C).

The problem is obviously a filename issue. How can this be fixed? Any ideas? I'd greatly appreciate any help.

A: 

I really think you're taking the hard route with this one. I do that kind of operations often, and use BRU for that kind of thing (zillion other alternatives are available) - it's small, portable, does its job terrifically.

Cannot see one good reason for wasting time with writing a new batch file for that.

ldigas
+1  A: 

How about replacing it with a nice simple ruby script?

Dir["*.mp3"].each_with_index{ |filename,index|
  File.rename filename, "Test-#{index}.mp3"
}
Chris
A: 

The fundamental issue is that a space is used as a word separator, ie, "foo bar.txt" is considered to be TWO files.

You need to somehow escape the arguments correctly for cmd.exe, so you need to check the documentation... Unfortunately for you, the rest of the world has moved on, and prefers to use any number of alternative shells (heck, even bash on cygwin), or as Chris suggested, to use another language instead.

Ruby, python, and perl are good choices.

Arafangion
A: 

if you don't mind using a windows script file, you can perform this functionality very easy, and quite possibly easier to read/update.

var path = "c:\\files";
var io = new ActiveXObject("Scripting.FileSystemObject");

Enumerator.prototype.each = function(f, c) {
  for (var i = 0; !this.atEnd(); this.moveNext()) {
    if (f.call(c, this.item(), i++, this)===false) break;
  }
  return this;
};

function fixedLength(n) {
  return (n < 100 ? "0" : "") + (n < 10 ? "0" : "") + n;
};

var results = [];
new Enumerator(io.GetFolder(path).Files).each(function(file, index) {
  var oldName = file.Name, newName = fixedLength(index+1) + ".mp3";
  if (/\.mp3$/i.test(oldName)) {
    // mp3 extension
    file.Name = newName;
    results.push(newName + " <-- " + oldName);
  }
});

WScript.Echo(results.join("\n"));

just save as renameMP3s.js or whatever.js you'd like and double-click.

Mister Lucky
Oh my goodness... Remind me never to use windows script files! I would not call this "very easy".
Arafangion
Thank you. I did try to use this, but couldn't get windows scripting host started (it said 'There is no script engine for file extension ".js"'
Majid
I have most of the functions already in a helper utility, so I extracted much of it here. It really can be even smaller if the functionality is only used ONE time, but rather show some code that can grow upon.
Mister Lucky
@majid4466: that's interesting, what windows version? if you don't mind?and do you see cscript and wscript in your win/sys folder?
Mister Lucky
+1  A: 

Try %%~fsa.mp3 instead of %%~na.mp3

as given at end in http://www.ss64.org/viewtopic.php?id=93

or add quotes to the longname..

lakshmanaraj
What resource did you use for documentation? (Modded this up because this is the only relevant answer thus far)
Arafangion
I have provided the URL where I could see this...
lakshmanaraj
Quotes should work, actually. Rename renames the first argument to the second. If your file happens to contain spaces then you must quote them. Otherwise junk happens :)
Joey
Yes Adding Quotes should work.
lakshmanaraj
A: 

Windows Vista supports bulk rename. Just select all the items in an Explorer window, and hit F2. Enter the filename you want (in this case "test") and hit enter. Bam, everyone re-named.

This will at least normalize it for you. Then you can write a script that puts quotes around everything, e.g. "%1", "%%~na.mp3", etc, and you're done.

jeffamaphone
thanks for the suggestion, but it it to run on xp, and xp renames as file.ext, file(1).ext, file(2).ext, ...
Majid
A: 

Have you tried putting quotes around the filenames for found?

rename "%%~na.mp3" instead of rename %%~na.mp3?

Patrick Cuff
A: 

First of all I would like to thank the friends who offered help through answers. But none was what I was looking for. Actually I arrived at a flawlessly working script using help provided by Spire posted as an answer to this question.

Here is the final code: (no need for line numbers this time)

rem @echo off
cls
set _number=%1

:F1TO10
IF NOT EXIST *.mp3. goto end
if %_number% gtr 9 goto F10TO100
for /f "usebackq delims=" %%x in (`dir /b *.mp3`) do rename %%~nsx.mp3 00%_number%-test.mp9
set /a _number +=1
goto F1TO10

:F10TO100
IF NOT EXIST *.mp3. goto end
if %_number% gtr 99 goto F100TO1000
for /f "usebackq delims=" %%x in (`dir /b *.mp3`) do rename %%~nsx.mp3 0%_number%-test.mp9
set /a _number +=1
goto F10TO100

:F100TO1000
IF NOT EXIST *.mp3. goto end
if %_number% gtr 999 goto end
for /f "usebackq delims=" %%x in (`dir /b *.mp3`) do rename %%~nsx.mp3 %_number%-test.mp9
set /a _number +=1
goto F100TO1000

:end
for /f %%a IN ('dir /b *.mp9') do rename %%~na.mp9 %%~na.mp3
echo Done.
Majid