@ECHO OFF
SETLOCAL
SET "relroot=u:\photos collection 01"
SET "oldmask=im age"
SET "newmask=new name"
SET "ext=jpg"
SET "skipped="
::
:: step 1 - ensure no 'newname*.ext' exists in the subtree
::
FOR /f %%i IN (
'DIR /s/b/a-d "%relroot%\%newmask%*.%ext%" 2^>nul^|FIND /c /v "" '
) DO IF NOT %%i==0 ECHO Files matching new mask already exist&GOTO :EOF
::
:: step 2 - list target files
::
:temploop
SET tempfile=%temp%\Photo%random%
IF EXIST "%tempfile%*" GOTO temploop
:: now have random tempfile name
(
FOR /f "delims=" %%i IN (
'DIR /s/b/a-d "%relroot%\%oldmask%*.%ext%" '
) DO (
ECHO %%~ni*%%~fi
)
)>"%tempfile%1"
::
:: Now do the rename
::
SET count=1000
SET prev=%newmask%
FOR /f %%i IN ('find /c "*" ^<"%tempfile%1"') DO IF %%i gtr 1000 ECHO %%i files - exceeds capacity&GOTO :eof
FOR /f "delims=*" %%i IN ('SORT "%tempfile%1"') DO (CALL :incren "%%i")
IF DEFINED skipped ECHO some files were NOT renamed&DIR /s/b/a-d "%relroot%\%oldmask%*.%ext%"
DEL "%tempfile%1"
GOTO :eof
:incren
:: repeat?
IF "%prev%"==%1 GOTO :EOF
:: no - process next name found
SET "prev=%~1"
FOR %%n IN (firstname secondname) DO (SET %%n=)
:: scan the tempfile, looking for matches to name found
FOR /f "usebackqtokens=1,2delims=*" %%m IN ("%tempfile%1") DO IF /i "%%m"=="%prev%" (
IF DEFINED firstname SET skipped=Y&IF NOT DEFINED secondname SET secondname=%%n
IF NOT DEFINED firstname SET firstname=%%n
)
IF DEFINED secondname SET firstname=%secondname%
ECHO REN "%firstname%" "%newmask%%count:~-3%.%ext%"
SET /a count+=1
GOTO :eof
Ну, не слишком сложно в конце концов.
Не совсем ушел с вашей спецификацией - я избегаю удаления файлов, поэтому я не переименовал цели с дублированными именами.
ПУТЕМ слишком много внимания уделяется попытке обработки глупых имен файлов ИМО. Если вы используете в своих именах символы, такие как !%^)=
, - ну, вы так умны - вы это понимаете.
Итак, при условии разумного имени и символов имени файла, чтобы работать!
Сначала настройте свой relative root
(начальный подкаталог) имя, используемые файлы, старые и новые, а также расширение. Я использую синтаксис set "var=string"
, чтобы избежать применения блуждающих терминальных пространств, которые невидимы и могут вызвать хаос. Обратите также внимание на то, что в присвоении строк пробелы по обе стороны от «=» значительны.
Первый шаг такой же документированный. Не уверен, что делать, если в дереве есть файлы, соответствующие новому имени, поэтому ничего не делайте. считая строки, которые появляются из dir /s/b/a-d
(каталог, с подкаталогами, базовая форма (так что без заголовков) и без имен каталогов) должно быть около 0, если все хорошо.
Мне нравится настраивать tempfiles, используя метод showm. Если в %temp%
нет имен, соответствующих выбранному случайному имени, тогда должно быть безопасно использовать это имя + любое приложение, которое вам нравится (так что вы можете создать много tempfiles, если это необходимо.)
Следующий шаг - получить подкаталог старых файлов в базовой форме снова, но на этот раз вывести файл tempfile. То, что выводится, является строкой для каждого файла, только структурированной как часть NAME (%%~ni
) звездочкой и полным именем файла (%%~fi
). Звездочка действует как разделитель столбцов и безопасна, потому что *
не может встречаться в имени файла.
Следующая фаза переименования. Мы начинаем COUNT
на 1000, чтобы мы могли использовать последние 3 символа для создания имени. Вы хотите начать с 001, просто используйте 1001 вместо этого. PREV
инициализируется значением, которое не может отображаться как имя файла, которое будет переименовано.
Снова подсчитайте имена, которые нужно переименовать. Если слишком много, бросьте корабль.
Следующим шагом является сортировка временного файла, поэтому результат будет обработан в порядке исходного базового имени файла (до «*» в каждой строке), а затем, если имя соответствует, в алфавитном порядке имени подкаталога (так как имя * родитель будет сортировать до имени * parent \ subdir). Каждое обнаруженное NAME затем передается в подпрограмму :incren
- цитируется для соответствия требованию пробелов в именах файлов.
Первое, что делает процедура INCREN, это проверить, повторяется ли имя предыдущего имени. Если это так, имя игнорируется (поскольку оно уже обработано). PREV
затем устанавливается на следующее имя. SET "prev=%~1"
удаляет цитату из первого параметра, а затем присваивает результат prev
и вмещающие кавычки предотвращения паразитного пространства от тычка в. firstname
и secondname
затем устанавливаются на [ничего]
Затем мы сканируем временный файл снова ищу совпадающее имя в качестве первого токена и присвоение второго токена (полное имя файла) до %%n
Когда первое найдено, первое имя не задано, поэтому установите его в полное имя файла. Если второе имя найдено, то firstname
уже будет установлен, поэтому установите SKIPPED
, чтобы указать, что проблема была обнаружена. Если второе имя файла еще не установлено, то установите secondname
на , что full-filename Если будут найдены дополнительные совпадения, то после того, как secondname
теперь установлен, ничего дальше делать не будет.
После того, как мы обработаем файл, у нас будет firstname
, установленное на первое полное имя файла (так как первый корневой каталог встречается с первым корнем), а secondname
будет установлен только в том случае, если было найдено 2 или более совпадающих имени. В этом случае установите значение firstname
на значение второго имени, которое будет находиться в нижнем подкаталоге.
Теперь сделайте RENAME. Я только ECHO
отредактировал его, но чтобы активировать, удалите ECHO
с линии ECHO REN...
. Мы знаем, что firstname
содержит полное имя файла, который нужно переименовать, и мы знаем, что структурой нового имени файла будет новая маска + последние 3 символа COUNT
+ точка + выбранное расширение.
и поднять счет для следующего переименования ...
Вот тестовый прогон с ECHO
удалены:
============= before =========
u:\photos collection 01\im age 612.jpg
u:\photos collection 01\im age 003.jpg
u:\photos collection 01\im age 005.jpg
u:\photos collection 01\im age 610.jpg
u:\photos collection 01\im age 009.jpg
u:\photos collection 01\im age 609.jpg
u:\photos collection 01\im age 505.jpg
u:\photos collection 01\selection 01\im age 001.jpg
u:\photos collection 01\selection 01\im age 004.jpg
u:\photos collection 01\selection 01\im age 005.jpg
u:\photos collection 01\selection 01\im age 006.jpg
============= run =========
some files were NOT renamed
u:\photos collection 01\im age 005.jpg
============= after =========
u:\photos collection 01\new name009.jpg
u:\photos collection 01\new name001.jpg
u:\photos collection 01\im age 005.jpg
u:\photos collection 01\new name008.jpg
u:\photos collection 01\new name005.jpg
u:\photos collection 01\new name007.jpg
u:\photos collection 01\new name006.jpg
u:\photos collection 01\selection 01\new name000.jpg
u:\photos collection 01\selection 01\new name002.jpg
u:\photos collection 01\selection 01\new name003.jpg
u:\photos collection 01\selection 01\new name004.jpg
ПримечаниеЭтот был выполнен Agains диск FAT, поэтому последовательность реальных файлов одинакова в обоих списках.
Я не верю, что существует разумный способ достижения 4) с использованием пакетных файлов. Для этого вам нужен настоящий язык программирования. Если вы хотите оставаться рядом со сценарием, рассмотрите PowerShell или VBScript/JScript. –