Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Батник для переименования файлов (http://forum.oszone.net/showthread.php?t=290750)

Школьник 5 11-11-2014 00:27 2427641

Батник для переименования файлов
 
Уважаемые знатоки! Очень прошу помочь со следующей задачкой: нужен батник для переименования файлов в папке.
Имена файлов нужно заменить на цифры 1.jpg, 2.jpg, 3.jpg .... n.jpg
Имена файлов могут быть любые - могут содержать символы % и !. В эти символы я, собственно, и уперся при попытке написать переименовалку самостоятельно:

@echo off
setlocal
for %%i in (*.jpg) do call:ren "%%i"
goto:eof

:ren
set "file=%~1"
ren %1 %file:!=%

переименовывает все, кроме файлов с символами "%" в названии. Если включаю setlocal enabledelayedexpansion и пробую аналогично убирать из названия %, то не срабатывает на файлах, в которых есть символы "!". Мог бы сделать по-очереди, но встречаются файлы, в которых есть и то и другое - их ничего не берет:((

Может кто что подскажет?

Georgio 11-11-2014 01:02 2427653

Код:

@for /f "delims=" %%i in ('"dir /a-d/b *.jpg"') do @set /a n+=1& cmd /v:on /c ren "%%i" !n!.jpg

Школьник 5 11-11-2014 01:23 2427656

[решено] Спасибо огромное!

Iska 11-11-2014 02:43 2427675

Цитата:

Цитата Школьник 5
Имена файлов нужно заменить на цифры 1.jpg, 2.jpg, 3.jpg .... n.jpg
Имена файлов могут быть любые - могут содержать символы % и !. В эти символы я, собственно, и уперся при попытке написать переименовалку самостоятельно »

Школьник 5, если отойти от принципа «Только пакетный файл!» (а там ещё надо, по-хорошему, проверять на уже существующие имена вида «1.jpg, 2.jpg, 3.jpg .... n.jpg»), то можно посмотреть в сторону: ReNamer.

Georgio 11-11-2014 05:26 2427689

Цитата:

Цитата Iska
а там ещё надо, по-хорошему, проверять на уже существующие имена вида «1.jpg, 2.jpg, 3.jpg .... n.jpg» »



Iska, ну эта проблема решаема:


Код:

@echo off

for /f %%i in ('"dir /a-d/b *.jpg| find /c /v """') do (
 for /l %%j in (1 1 %%i) do (
  call ren %%j.jpg %%j_%%random%%%%random%%.jpg 2>nul
  )
 )
for /f "delims=" %%i in ('"dir /a-d/b *.jpg"') do (
 set /a n+=1
 cmd /v:on /c ren "%%i" !n!.jpg
 )

exit /b


.




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


Код:

@echo off

for /f "delims=" %%i in ('"dir /a-d/b *.jpg"') do (
 set /a n+=1
 (
 call set /p="%%n%% "<nul
 echo %%i
 )>>.tmp
 )
for /f "tokens=1*" %%i in ('"type .tmp& del .tmp"') do (
 ren "%%j" %%i.jpg
 )

exit /b


.




Таким образом, если объединить оба решения, получится такой код:


Код:

@echo off

for /f %%i in ('"dir /a-d/b *.jpg| find /c /v """') do (
 for /l %%j in (1 1 %%i) do (
  call ren %%j.jpg %%j_%%random%%%%random%%.jpg 2>nul
  )
 )
for /f "delims=" %%i in ('"dir /a-d/b *.jpg"') do (
 set /a n+=1
 (
 call set /p="%%n%% "<nul
 echo %%i
 )>>.tmp
 )
for /f "tokens=1*" %%i in ('"type .tmp& del .tmp"') do (
 ren "%%j" %%i.jpg
 )

exit /b


.

temphard 10-11-2019 18:23 2895590

Georgio, Спасибо за код.
Подскажите пожалуйста, как в этом коде указать конкретный путь к каталогу? Чтобы переименование происходило именно в нем.
Код:

@for /f "delims=" %%i in ('"dir /a-d/b *.mp3"') do @set /a n+=1& cmd /v:on /c ren "%%i" !n!.mp3

megaloman 10-11-2019 22:39 2895617

Цитата:

Цитата Школьник 5
Имена файлов могут быть любые - могут содержать символы % и !. В эти символы я, собственно, и уперся при попытке написать переименовалку самостоятельно »

temphard, Если такая пьянка, то это не задача для CMD. Вот VBS.
Код:

BoxIn = "Z:\Box_In"

Set FSO = CreateObject("Scripting.FileSystemObject")

On Error Resume Next
Set AllF = FSO.GetFolder(BoxIn).Files
If Err.Number <> 0 Then
    MsgBox """" + BoxIn + """" + vbCrLf + vbCrLf + "Open folder, Err.Number=" + CStr(Err.Number) + vbCrLf + Err.Description
    WScript.Quit 1
End If

With CreateObject("VBScript.RegExp")
    .Pattern = "^~~~.*$"
    .IgnoreCase = True
    .Global = True
    For Each FileIn In AllF
        If Not .Test(FileIn.Name) Then
            FSO.MoveFile FileIn, BoxIn + "\~~~" + FileIn.Name
        End If
    Next

    i = 0
    j = 100000
    For Each FileIn In AllF
        If .Test(FileIn.Name) Then
            i = i + 1
            j = j + 1
            FSO.MoveFile FileIn, BoxIn + "\" + CStr(i) + "." + FSO.GetExtensionName(FileIn)
'            FSO.MoveFile FileIn, BoxIn + "\" + Mid(CStr(j), 2) + "." + FSO.GetExtensionName(FileIn)
        End If
    Next
End With
On Error GoTo 0

Красный закомментированный вариант для переименования файлов в вид 00001.ext 00002.ext ....
Если нужен такой вид, то закомментируйте предыдущую строку и откомментируйте эту (убрать ')
При этом если файлов более 99999, то увеличьте число нулей в j = 100000

megaloman 11-11-2019 13:24 2895677

temphard,
Вот еще вариант. Введен фильтр на расширение файлов в папке.
Можно указать папку явно. Можно указать её в аргументе в кавычках при вызове скрипта.
Можно создать ярлык на этот скрипт и в проводнике затягивать обрабатываемую папку на него
Код:

BoxIn = "Z:\Box_In"    ' Путь к папке (при отсутствии аргумента в вызове скрипта)
Ext = "mp3"            ' Расширение файлов

With WScript.Arguments
    If .Count <> 0 Then
        BoxIn = .Item(0)
    End If
End With

Set FSO = CreateObject("Scripting.FileSystemObject")

On Error Resume Next
Set AllF = FSO.GetFolder(BoxIn).Files
If Err.Number <> 0 Then
    MsgBox """" + BoxIn + """" + vbCrLf + vbCrLf + "Open folder, Err.Number=" + CStr(Err.Number) + vbCrLf + Err.Description
    WScript.Quit 1
End If

With CreateObject("VBScript.RegExp")
    .Pattern = "^.*\." + Ext + "$"
    .IgnoreCase = True
    .Global = True
    For Each FileIn In AllF
        If .Test(FileIn.Name) Then
            FileIn.Name = FileIn.Name + "~~~"
        End If
    Next

    i = 0
    j = 100000
    .Pattern = "^.*\." + Ext + "~~~$"
    For Each FileIn In AllF
        If .Test(FileIn.Name) Then
            i = i + 1
            j = j + 1
            FileIn.Name = CStr(i) + "." + Ext
'            FileIn.Name = Mid(CStr(j), 2) + "." + Ext
        End If
    Next
End With
On Error GoTo 0

MsgBox "Done"


temphard 29-11-2019 14:14 2898483

Цитата temphard:
Georgio »
Код:

@for /f "delims=" %%i in ('"dir /a-d/b *.mp3"') do @set /a n+=1& cmd /v:on /c ren "%%i" !n!.mp3 »[/q]
Извините, я новичок и мне не понятно как в данном коде указать путь к конкретному каталогу, например С:\file\
Пожалуйста объясните подробнее, спасибо.

alpap 29-11-2019 17:09 2898516

Цитата:

Цитата temphard
указать путь »

здесь
Цитата:

Цитата temphard
...in ('dir /a-d/b "С:\file\*.mp3"') do...»

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

temphard 29-11-2019 18:30 2898530

Цитата:

Цитата alpap
и обратите внимание на парные кавычки »

Что-то я совсем запутался...
Код:

@echo off
for /f %%i in ('dir /a-d/b "С:\file\*.mp3"'| find /c /v """') do (
 for /l %%j in (1 1 %%i) do (
  call ren %%j.mp3 %%j_%%random%%%%random%%.mp3 2>nul
  )
 )
for /f "delims=" %%i in ('"dir /a-d/b *.mp3"') do (
 set /a n+=1
 (
 call set /p="%%n%% "<nul
 echo %%i
 )>>.tmp
 )
for /f "tokens=1*" %%i in ('"type .tmp& del .tmp"') do (
 ren "%%j" %%i.mp3
 )
exit /b

Не работает, где-то ошибка...

alpap 29-11-2019 21:10 2898553

как минимум:
Цитата:

Цитата temphard
in ('dir /a-d/b "С:\file\*.mp3"'| find /c /v """') do »

Код:

in ('dir /a-d/b "С:\file\*.mp3"^| find /c /v ""') do
или
Код:

in ('"dir /a-d/b "С:\file\*.mp3"| find /c /v """') do
а вообще очень сумбурно код написан, лучше если вы озвучите свою задачу и в деталях, мы поможем написать код и правильно и красиво.

DJ Mogarych 29-11-2019 21:16 2898554

Powershell, вроде работает:

Код:

$folder = 'C:\temp\2'
$c = 1

(dir "$folder").foreach({
Rename-Item $_.fullname -NewName $("$c" + "$($_.extension)")
$c++
})


temphard 29-11-2019 22:50 2898573

Цитата:

Цитата alpap
лучше если вы озвучите свою задачу и в деталях »

Да все просто, пользуюсь этим кодом, чтобы переименовывать в цифровой последовательности 1,2,3... mp3 файлы.
Скрытый текст
Код:

@echo off

for /f %%i in ('"dir /a-d/b *.mp3| find /c /v """') do (
 for /l %%j in (1 1 %%i) do (
  call ren %%j.mp3 %%j_%%random%%%%random%%.mp3 2>nul
  )
 )
for /f "delims=" %%i in ('"dir /a-d/b *.mp3"') do (
 set /a n+=1
 (
 call set /p="%%n%% "<nul
 echo %%i
 )>>.tmp
 )
for /f "tokens=1*" %%i in ('"type .tmp& del .tmp"') do (
 ren "%%j" %%i.mp3
 )

exit /b


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

DJ Mogarych 29-11-2019 23:05 2898576

Более продвинутый вариант, с подсчётом кол-ва файлов в папке и на этом основании подстановка нулей в начало:
Код:

$files = dir 'C:\temp\2' -file
$digits = (($files.count -split '') -match "\d").count
$c = 1

$files.foreach({
Rename-Item $_.fullname -NewName (("{0:D$digits}" + "$($_.extension)") -f $c++)
})

Идея: https://stackoverflow.com/questions/...fixes/18305871

temphard 29-11-2019 23:37 2898577

Цитата:

Цитата DJ Mogarych
Более продвинутый вариант »

Спасибо, но мне нужна именно такая нумерация 1,2,3... и обязательно указать расширение файлов, так как кроме mp3, в каталоге находятся другие файлы и их трогать нельзя.

alpap 30-11-2019 01:17 2898585

temphard,
Цитата:

Цитата temphard
Но находясь в другом месте, код не срабатывает »

не знаю как вы там запускаете
в моем коде путь указан в переменной, можно задать свой путь или изменив его в переменной непосредственно или задав первым параметром, тогда запускать так:
Код:

name.bat "C:\Papka"
если раскомментировать 3-ю строку (и закомментировать 2-ю, хотя необязательно), то можно вводить путь по запросу, при этом если ничего не ввести, путь, заданный в переменной, останется по-умолчанию.
Код:

@echo off
set "sdir=C:\Papka"& if not "%~1"=="" set "sdir=%~1"
:: set "sdir=C:\Papka"& echo Введите путь:& set /p sdir=
set "ext=mp3"

pushd "%sdir%"
 for /f "tokens=1* delims=[]" %%a in ('dir /a-d/b "*.%ext%"^|find /n /v ""') do ren "%%b" "%%a%%~xb"
popd
pause


DJ Mogarych 30-11-2019 08:46 2898596

Цитата:

Цитата temphard
1,2,3... и обязательно указать расширение файлов »

Да какие проблемы-то:
Код:

$files = dir "C:\temp\1\*.mp3"
$c = 1

$files.foreach({
Rename-Item $_.fullname -NewName $("$c" + "$($_.extension)")
$c++
})


megaloman 30-11-2019 19:43 2898607

temphard, Не хотел встревать, но:
Вот вариант CMD для нумерации вида 1 2 3 ...
Код:

@Echo Off
        Set "BoxIn=Z:\Box_In"
        Set "Ext=mp3"

        If Not "%1"=="" Set "BoxIn=%~1"

        For %%f In ("%BoxIn%\*.%Ext%") Do Ren "%%f" "%%~nxf.~tmp"
        Set /A i=0
        For %%f In ("%BoxIn%\*.%Ext%.~tmp") Do (
                Call Set /A i+=1
                Call Ren "%%f" "%%i%%.%Ext%"
        )
Exit /B 0

Вот вариант CMD для нумерации вида 0001 0002 0003 ..0123 ...
Код:

@Echo Off
        Set "BoxIn=Z:\Box_In"
        Set "Ext=mp3"

        If Not "%1"=="" Set "BoxIn=%~1"

        For %%f In ("%BoxIn%\*.%Ext%") Do Ren "%%f" "%%~nxf.~tmp"
        Set /A i=10000
        For %%f In ("%BoxIn%\*.%Ext%.~tmp") Do (
                Call Set /A i+=1
                Call Ren "%%f" "%%i:~1%%.%Ext%"
        )
Exit /B 0

Обрабатываемую папку можно явным образом прописать в строке по образцу:
Set "BoxIn=Z:\Box_In"
Можно указать её в аргументе в кавычках при вызове скрипта.
Например: kuku.bat "D:\tralala\lamca drica ca"
Можно создать ярлык на этот скрипт и в проводнике затягивать обрабатываемую папку на него.
Но, если в именах файлов есть спецсимволы, берите vbs.

temphard 30-11-2019 21:03 2898618

Всем спасибо за помощь, для моих нужд ваших предложений более, чем достаточно.
Цитата:

Цитата megaloman
Не хотел встревать, но »

Ещё небольшой вопросик: в каталоге находится несколько десятков тысяч *.mp3 файлов и скрипту для его выполнения необходимо определённое время, а можно ли сделать так, чтобы скрипт по какому-то алгоритму выбирал первый "попавшийся" *.mp3 файл и переименовывал его в 1.mp3?
В случае, если файл с таким именем уже существует, чтобы он перезаписывался. Главное чтобы скрипт работал быстро.
То есть для меня нет так важно, чтобы все файлы были пронумерованы, но чтобы один mp3 файл точно имел имя 1.mp3
Дело в том, что файл 1.mp3 постоянно удаляется (это так надо) и тем не менее такой файл должен всё время появляться в данном каталоге из числа других mp3 файлов.
Не обессудьте, если мои объяснения кажутся странными.

megaloman 30-11-2019 21:27 2898627

Цитата:

Цитата temphard
чтобы скрипт по какому-то алгоритму выбирал первый "попавшийся" *.mp3 файл и переименовывал его в 1.mp3 »

Беру самый старый, переименовываю его в 1, остальные не трогаю
Код:

@Echo Off
        Set "BoxIn=Z:\Box_In"
        Set "Ext=mp3"

        If Not "%1"=="" Set "BoxIn=%~1"

        If Exist "%BoxIn%\1.%Ext%" Del "%BoxIn%\1.%Ext%"
        For /F "usebackq delims=" %%f In (`2^>nul Dir "%BoxIn%\*.%Ext%" /B /A:-D /O:D`) Do (
                Ren "%BoxIn%\%%f" "1.%Ext%"
                GoTo :Continue
        )
        :Continue
Exit /B 0


temphard 30-11-2019 21:58 2898637

Цитата:

Цитата megaloman
Беру самый старый »

Спасибо, то что надо!


Время: 22:09.

Время: 22:09.
© OSzone.net 2001-