Проблема пакетного переименования при работе со специальными символами в имени файла - PullRequest
2 голосов
/ 26 марта 2009

У меня есть несколько сотен * .mp3 файлов в c: \ files. Там есть все мыслимые имена файлов, такие как

  • milad.mp3 (хорошее поведение)
  • эй, ты.mp3 (пробел в имени файла)
  • systemofadown.mp3 (длинное имя файла)
  • howdy (1) .mp3 (скобки в имени файла)

и любая комбинация трех последних условий. Я хочу переименовать файлы в 001-test.mp3, 002-mp3, ... Неважно, какой файл получит какое имя. написал командный файл, чтобы сделать переименование. Вот мой код (с добавленными номерами строк):

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

Этот код прекрасно работает для имен файлов с хорошим поведением (т.е. без пробелов, без скобок, длиной не более 8 символов). Но если у меня есть хотя бы один файл с плохим поведением имени файла, сценарий прерывается (он бесконечно зацикливается, пока я не остановлю его нажатием Ctrl-C).

Проблема, очевидно, в имени файла. Как это можно исправить? Есть идеи? Я был бы очень признателен за любую помощь.

Ответы [ 8 ]

2 голосов
/ 26 марта 2009

Попробуйте %%~fsa.mp3 вместо %%~na.mp3.

как указано в конце в http://www.ss64.org/viewtopic.php?id=93

или добавить кавычки к длинному имени ..

1 голос
/ 26 марта 2009

Как насчет замены его на хороший простой скрипт ruby?

Dir["*.mp3"].each_with_index{ |filename,index|
  File.rename filename, "Test-#{index}.mp3"
}
0 голосов
/ 31 марта 2009

Прежде всего я хотел бы поблагодарить друзей, которые предложили помощь через ответы. Но ни один не был тем, что я искал. На самом деле я пришел к безупречно работающему сценарию, используя помощь, предоставленную Spire , опубликованную в ответ на этот вопрос .

Вот окончательный код: (на этот раз номера строк не нужны)

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.
0 голосов
/ 26 марта 2009

Вы пытались поставить кавычки вокруг имен файлов for найдено?

rename "%%~na.mp3" вместо rename %%~na.mp3?

0 голосов
/ 26 марта 2009

Windows Vista поддерживает массовое переименование. Просто выберите все элементы в окне проводника и нажмите F2. Введите имя файла, который вы хотите (в данном случае «тест») и нажмите Enter. Бэм, все переименованы.

Это, по крайней мере, нормализует это для вас. Затем вы можете написать скрипт, который будет заключать в кавычки все, например, "% 1", "%% ~ na.mp3" и т. Д., И все готово.

0 голосов
/ 26 марта 2009

Если вы не возражаете против использования файла сценария Windows, вы можете выполнить эту функцию очень легко и, возможно, проще для чтения / обновления.

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"));

просто сохраните как renameMP3s.js или как угодно .js и дважды щелкните.

0 голосов
/ 26 марта 2009

Фундаментальная проблема заключается в том, что в качестве разделителя слов используется пробел, т. Е. "Foo bar.txt" считается двумя файлами.

Вам нужно как-то корректно экранировать аргументы для cmd.exe, поэтому вам нужно проверить документацию ... К сожалению, для вас весь остальной мир продвинулся дальше и предпочитает использовать любое количество альтернативных оболочек (черт возьми) , даже bash на cygwin), или, как предложил Крис, вместо этого использовать другой язык.

Ruby, python и perl - хороший выбор.

0 голосов
/ 26 марта 2009

Я действительно думаю, что вы выбираете сложный путь с этим. Я часто выполняю такие операции и использую BRU для такого рода вещей (доступно еще миллионы других альтернатив) - он небольшой, портативный и выполняет свою работу ужасно.

Не вижу одной веской причины, чтобы тратить время на написание для этого нового пакетного файла.

...