[CMD] Переименование файлов по шаблону с удалением части символов из имени

alex_diablo

Активный пользователь
Сообщения
144
Реакции
9
Доброго времени суток!
появилась такая задачка:

есть папка с большим количеством файлов в ней.
файлы вида:
456123agents_preview_pack_004_BC15F9146A415178B95BE92EB26DD92F-56.unity3d

нужен батник, который бы переименовывал по следующему шаблону:

из имени файла с конца удалял заданное число символов, например 32, в итоге
переименованный файл должен принять вид:

456123agents_preview_pack_004_BC1.unity3d

нашел как переименовывать просто файлы:

CMD/BATCH:
for /f "tokens=*" %%a in ('dir /b PATH\*.*') do ren PATH\%%a Prefix%%a

CMD/BATCH:
set thePATH=C:\test
for %%I in (*.txt) do ren "%thePATH%\%%~nxI" "%%~nI.dat"

CMD/BATCH:
for %%I in ("*.zdt") do (
for /f "delims=-. tokens=1,2,3" %%A in ('echo %%I') do (
ren %%I %%A-wp%%B.%%C )
)

но никак не могу понять, как удалять символы с конца имени файла в данном случае...

помогите пожалуйста.
 
Последнее редактирование:

alex_diablo

Активный пользователь
Сообщения
144
Реакции
9
вобщем, поковырялся и сделал вот так:

CMD/BATCH:
@echo off
set ext=unity3d
echo.
echo. Rename files started...
for %%I in (%~dp0*.%ext%) do (
set name1=%%I
set name2=%%~nI
call :rename
)
:rename
ren "%name1%" "%name2:~0,-33%.%ext%"
exit /b

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

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
alex_diablo, все Вы нормально сделали.
Двойное раскрытие переменной можно организовать так:
CMD/BATCH:
@echo off
set ext=unity3d
set TrimCnt=33
echo.
echo. Rename files started...
for %%I in (%~dp0*.%ext%) do (
  set "name1=%%I"
  set "name2=%%~nI"
  call :rename
)
goto :eof
:rename
  call ren "%name1%" "%%name2:~0,-%TrimCnt%%%.%ext%"
exit /b
 
Последнее редактирование:

alex_diablo

Активный пользователь
Сообщения
144
Реакции
9
а как сделать, чтобы не нужно было высчитывать количество символов? ну вот например, в имени файла есть 4 символа нижнего подчеркивания...
и нужно все символы, которые после последнего знака подчеркивания - убрать, т.е. файл 456123agents_preview_pack_004_BC15F9146A415178B95BE92EB26DD92F-56.unity3d
после переименования должен иметь вид: 456123agents_preview_pack_004.unity3d

пробовал задействовать вот этот вариант:

CMD/BATCH:
for %%I in ("*.zdt") do (
for /f "delims=-. tokens=1,2,3" %%A in ('echo %%I') do (
ren %%I %%A-wp%%B.%%C )
)


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

надеюсь понятно объяснил.
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
А не получится ли так, что среди тех файлов, что нужно переименовать попадется
456123agents_preview_pack_004
у которого соответственно урежется часть _004
?
 

alex_diablo

Активный пользователь
Сообщения
144
Реакции
9
alex_diablo, все Вы нормально сделали.
Двойное раскрытие переменной можно организовать так:
CMD/BATCH:
@echo off
set ext=unity3d
set TrimCnt=33
echo.
echo. Rename files started...
for %%I in (%~dp0*.%ext%) do (
  set "name1=%%I"
  set "name2=%%~nI"
  call :rename
)
goto :eof
:rename
  call ren "%name1%" "%%name2:~0,-%TrimCnt%%%.%ext%"
exit /b


а в данной версии кода хотелось бы всю команду
CMD/BATCH:
:~0,33
поместить в переменную TrimCnt
чтобы в конечном итоге можно было проводить с ней различные манипуляции в зависимости от потребностей. чтобы в саму строчку переименования не лазить.
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
2. Можно как-то привязаться к кол-ву знаков подчеркивания,
или может получится, что таких знаков = 3, а строку все равно нужно урезать до 2-ух знаков подчеркивания ?
 

alex_diablo

Активный пользователь
Сообщения
144
Реакции
9
А не получится ли так, что среди тех файлов, что нужно переименовать попадется
456123agents_preview_pack_004
у которого соответственно урежется часть _004
?
нет. т.к. заведомо известно, что в одно время в одной папке находятся файлы, именнованные все по одному шаблону. но в разное время количество разделителей может быть разное, поэтому и нужна возможность задать количество разделителей, чтобы подстраивать скрипт.
 

alex_diablo

Активный пользователь
Сообщения
144
Реакции
9
2. Можно как-то привязаться к кол-ву знаков подчеркивания,
или может получится, что таких знаков = 3, а строку все равно нужно урезать до 2-ух знаков подчеркивания ?

поясню задачу: есть файлы вида: agents_preview_pack_002_1171C57D8808635BA4F8AFAEA5149D8D.unity3d
agents_preview_pack_004_1171C57D8808635BA4F8AFAEA5149D8D.unity3d
agents_preview_archive_010_1171C57D8808635BA4F8AFAEA5149D8D.unity3d

и т.д.

вот в них нужно убирать хеш (символы вида 1171C57D8808635BA4F8AFAEA5149D8D)

т.е. после манипуляций переименования все файлы должны принять вид:
agents_preview_pack_002
agents_preview_pack_004
agents_preview_archive_010

и т.д.
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
Понял. Горе. Отвык писать батники. Сейчас подумаю, как можно.
 

alex_diablo

Активный пользователь
Сообщения
144
Реакции
9
вы хотя бы отвыкли... а я так и не научусь никак... особенно циклы, разбор строк... темный лес...

в первой версии скрипта вынес вычитание символов полностью в переменную...

CMD/BATCH:
::@echo off
set ext=unity3d
set TrimCnt=:~0,-33
echo.
echo. Rename files started...
for %%I in (%~dp0*.%ext%) do (
set name1=%%I
set name2=%%~nI
call :rename
)
goto :eof
:rename
call ren "%name1%" "%%name2%TrimCnt%%%.%ext%"
exit /b
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
CMD/BATCH:
@echo off
SetLocal EnableExtensions

set ext=unity3d

:: После какого по счету знака _ нужно урезать?
set Cnt=4

For /f "delims=" %%a in ('2^>NUL dir /b /a-d "*.%ext%"') do (
  for /f "tokens=%Cnt%* delims=_" %%b in ("%%~na") do (
  if "%%c" neq "" (
  set "name1=%%a"
  set "name2=%%c"
  call :rename
  )
  )
)
goto :eof
:rename
  call ren "%name1%.%ext%" "%%name1:_%name2%=%%.%ext%"
exit /B

Только учтите, что если та, часть фразы, которую мы урезаем попадется еще раз в средине файла, то и там тоже будет урезана (пример: 11_22_55_44_55 -> 11_22_44).
в первой версии скрипта вынес вычитание символов полностью в переменную...
:)
 

monowar

Активный пользователь
Сообщения
397
Реакции
625
Попробовал применить этот батник к файлам 3xhumed-Mega-Games-Pack-18-Half-Life-Ricochet-2.ico, 2. -Half-Life-2-Capture-the-Flag-2.ico и др. но не подрезает имена батник (ext заменил на ico , delims=_ на delims=-) . Где я ошибаюсь ?
set Cnt=4 - это переменная?
 
Последнее редактирование:

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
Разделитель в ещё одном месте был + изначально в скрипте ошибочка, лишние .%ext%

CMD/BATCH:
@echo off
SetLocal EnableExtensions

set ext=ico

:: После какого по счету знака _ нужно урезать?
set Cnt=4
set delim=-

For /f "delims=" %%a in ('2^>NUL dir /b /a-d "*.%ext%"') do (
  for /f "tokens=%Cnt%* delims=%delim%" %%b in ("%%~na") do (
    if "%%c" neq "" (
      set "name1=%%a"
      set "name2=%%c"
      call :rename
    )
  )
)
goto :eof
:rename
  call ren "%name1%" "%%name1:%delim%%name2%=%%"
exit /B

уфф, привет 2015 год
 

monowar

Активный пользователь
Сообщения
397
Реакции
625
(Если я Вас не замучил ,то возник ещё вопрос (в голове не совсем уложились token)) А как обрезать часть названия файла 3xhumed-Mega-Games-Pack-18-Half-Life-Ricochet-2.ico до 3xhumed-Mega-Games-Pack-18-Half-Life-Ricochet.ico до Ricochet.ico и 3xhumed-Mega-Games-Pack-18-Half-Life-Ricochet.ico до Life-Ricochet.ico
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
Вообще Batch мало пригоден для разбивания по токенам в обратном порядке, так что только с помощью костылей.
Вот держи и разбивай как хочешь:

CMD/BATCH:
@echo off
setlocal EnableExtensions

set ext=ico
set delim=-

For /f "delims=" %%a in ('2^>NUL dir /b /a-d "*.%ext%"') do (
  call :GetLastToken "%%a"
  call :rename "%%a"
)
pause
goto :eof

:rename
  ren "%~1" "%F[1]%%~x1"
exit /B

:GetLastToken
  set "name=%~n1"
  set cnt=0
:do
  :: узнаем кол-во токенов
  for /f "tokens=1* delims=%delim%" %%a in ("%name%") do (
    set "name=%%b"
    set /a cnt+=1
    if "%%b" neq "" goto do
  )
  set /a cnt-=1
  set "name=%~n1"
:do2
  :: занесем в псевдо-массив в обратном порядке
  for /f "tokens=1* delims=%delim%" %%a in ("%name%") do (
    set "F[%cnt%]=%%a"
    set "name=%%b"
    set /a cnt-=1
    if "%%b" neq "" goto do2
  )
  :: при необходимости, распечатать все
  ::SetLocal EnableDelayedExpansion
  ::for /L %%a in (0,1,10) do echo F[%%a]=!F[%%a]!
  ::EndLocal
exit /b

Все токены помещены в псевдо-массив F[] в обратном порядке:

F[0]=2
F[1]=Ricochet
F[2]=Life
F[3]=Half
F[4]=18
F[5]=Pack
F[6]=Games
F[7]=Mega
F[8]=3xhumed

Используй какой захочешь и в какой угодно комбинации.
 

monowar

Активный пользователь
Сообщения
397
Реакции
625
@Dragokas, Костыль знатный :Good: !!! Как я понял F[ ] это токены. Попробовал оставить два F[0-1]- почему-то не получается из-за - (тире) в имени ?
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,780
Реакции
6,234
Как я понял F[ ] это токены.
F[] это псевдо-массив, элементы которого содержат токены в обратном порядке.

Попробовал оставить два F[0-1]- почему-то не получается из-за - (тире) в имени ?
потому что вы выдумали собственный синтаксис. Вот так нужно, как и с любыми переменными: %F[0]%%F[1]%
 
Сверху Снизу