Компьютерный форум 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=205893)

shao 30-04-2011 13:13 1667976

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

Например:
Код:

textA_textB_text001.xxx
textA_textB_text002.xxx
.......................................

на

001_textA_textB.xxx
002_textA_textB.xxx
................................

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

Например так:
Код:

textA_textB_text051.xxx
textA_textB_text052.xxx
.......................................

на

051textA_textB.xxx
052textA_textB.xxx
..............................

Спасибо!

Foreigner 30-04-2011 15:40 1668043

shao,
Например переименовываем 100 файлов *.txt. Без привязки к исходному названию:
Код:

@echo off
setlocal

for %%i in (*.txt) do call:rename "%%i"
goto:eof

:rename
set /a cnt+=1
set "pref=00%cnt%"
ren %1 "%pref:~-3%_newname.txt"

PS. Не 100 а до 999

shao 01-05-2011 11:17 1668375

Foreigner, Отлично! Спасибо - работает.

Пожалуйста, ещё бы вариант привязки к исходному названию. Чтобы не вносить название каждый раз
вручную. Вот так:

Код:

textA_textB_text001.xxx
textA_textB_text002.xxx
.......................................

на

001_textA_textB.xxx
002_textA_textB.xxx
................................

И, наберусь наглости ещё попросить обЪяснить как работает Ваш код.. :)

Foreigner 01-05-2011 12:15 1668398

shao,
Цитата:

вариант привязки к исходному названию
Этот вариант только для переименовывания конкретно ваших файлов
Цитата:

обЪяснить как работает
Код:

@echo off
setlocal

:: Перебираем все файлы *.ххх в текущей директории и каждый
:: из них передаём в процедуру переименовывания (метка :ren)
for %%i in (*.xxx) do call:ren "%%i"

:: Выход из батника
goto:eof

:: Здесь переименовываем поступивший из цикла for файл
:ren

:: Переменная old получает значение имени файла
set "old=%~n1"

:: Переменная pref получает подстроку -- 3 последних символа в имени файла, т.е. номер
set "pref=%old:~-3%"

:: Переименовываем файл
ren %1 "%pref%_%old:~0,-3%%~x1"

:: Где:
:: %1 -- поступивший файл
:: %old:~0,-3% -- подстрока из имени с 1 до -3 символа ( т.е. отрезали номер )
:: %~x1 -- расширение файла ( .ххх )


shao 02-05-2011 00:04 1668695

Foreigner, спасибо большое за второй скрипт и обЪяснение.
И если не затруднит - обЪясните ещё пожалуйста этот момент:

Код:

.......
:rename
set /a cnt+=1
set "pref=00%cnt%"
ren %1 "%pref:~-3%_newname.txt"

из первого скрипта.

Foreigner 02-05-2011 08:24 1668777

shao,
Код:

:: Увеличиваем с каждым вызовом порядковое число ( перем. %cnt% ) на 1 
set /a cnt+=1

:: Определяем числовой префикс для будущего переименования ( 001, 0010, 00122 и т.д. )
set "pref=00%cnt%"

:: Переименовываем
ren %1 "%pref:~-3%_newname.txt"

:: Где %1 -- исходное имя файла, переданное из цикла for
:: %pref:~-3% -- префикс, приведенный к одной длине, взяты три последние символа ( 001, 010, 122 ).


shao 02-05-2011 11:18 1668833

Foreigner, Спасибо Вам за помощь!

Всё понятно , кроме одного. Что такое "cnt" ?

Foreigner 02-05-2011 11:26 1668836

Цитата:

Цитата shao
Что такое "cnt" ? »

=) Просто название переменной. ( от англ. 'count' )

Iska 02-05-2011 13:49 1668910

Цитата:

Цитата shao
Что такое "cnt" ? »

При использовании в операторе «set» формы «/a» (целочисленные вычисления) нет необходимости использовать «%»/«!» для раскрытия переменных окружения, сие делается автоматически, причём всегда как отложенное раскрытие.

amel27 03-05-2011 16:18 1669580

Цитата:

Цитата Iska
При использовании в операторе «set» формы «/a» (целочисленные вычисления) нет необходимости использовать «%»/«!» для раскрытия переменных окружения, сие делается автоматически, причём всегда как отложенное раскрытие. »

не нужно путать подстановки CMD (в т.ч. отложенные) и "подстановки" SET (у которого свой парсер)
читать дальше »
Код:

@Echo Off
SetLocal EnableDelayedExpansion

set/a "$x=$x+1,$x=$x+1,$x=$x+1"
set/a "$y=!$y!+1,$y=!$y!+1,$y=!$y!+1"

set $
pause>nul


Iska 03-05-2011 22:05 1669784

amel27, спасибо. Я не путаю. Про парсер знаю. Должно быть, Вас смутило упоминание «как отложенное раскрытие».

amel27 04-05-2011 02:03 1669893

Iska, а замечание и не для Вас, а для тех кто будет читать пост после справки ;)

Iska 04-05-2011 02:59 1669902

amel27, спасибо, ясно.

shao 07-05-2011 18:32 1672005

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

Пример:
Код:

aaaaa 01f01 - bbbb bbbb.txt
aaaaa 01f04 - b bbbb.txt
aaaaa 01f10 - bbb bbb.txt

на

01_bbbb bbbb.txt
02_b bbbb.txt
03_bbb bbb.txt

Я , вот попробовал со своими скудными знаниями что-то сделать... но это жалкие потуги какие-то:

Код:

@echo off
setlocal

for %%i in (*.txt) do call:ren "%%i"

:ren
set /a cnt+=1
set "pref=00%cnt%"
set "name=%~n1"

ren %1 "%pref:~-2%_%name:как здесь-не знаю%%~x1"

Прошу помощи, пожалуйста - правильно ли составил и ,
как отсечь стандартный текст с номерами в начале названия в переменной %name% ?

amel27 07-05-2011 18:56 1672013

Цитата:

Цитата shao
как отсечь стандартный текст с номерами в начале названия в переменной %name% ? »

т.е. нужно пропустить в имени первые 14 символов?
Код:

ren "%1" "%pref:~-2%_%name:~14%%~x1"

shao 07-05-2011 19:07 1672024

Цитата:

Цитата amel27
т.е. нужно пропустить в имени первые 14 символов? »

Да , именно. Спасибо за помощь и оперативность!!!!

.......

Почему - то "ошибка в синтаксисе команды...."
Код:

@echo off
setlocal

for %%i in (*.txt) do call:ren "%%i"

:ren
set /a cnt+=1
set "pref=00%cnt%"
set "name=%~n1"

ren "%1" "%pref:~-2%_%name:~14%%~x1"


amel27 07-05-2011 19:16 1672034

shao, после строки с FOR (перед REN) нужно поставить выход из скрипта - EXIT, чтобы предотвратить холостой вход в процедуру REN
а по поводу ошибок - включайте "@echo on" и смотрите, на какой строке валится

shao 07-05-2011 20:28 1672067

amel27,
Цитата:

Цитата amel27
, а по поводу ошибок »

Вот так:
Код:

@echo off
setlocal

for %%i in (*.txt) do call:ren "%%i"


:ren
set /a cnt+=1
set "pref=00%cnt%"
set "name=%~n1"

ren %1 "%pref:~-2%_%name:~14%%~x1"

батник работает без "EXIT" после "FOR"
и без кавычек :
Код:

ren %1
В таком варианте :
Код:

ren "%1" ........
была ошибка синтаксиса....
Почему ?

Iska 07-05-2011 21:13 1672090

Код:

for %%i in (*.txt) do call:ren "%%i"
exit

:ren

ren "%~1"
exit /b


shao 07-05-2011 21:49 1672120

Iska, спасибо!

Работает так :
Код:

ren %1  …
и так:
Код:

ren "%~1" …
А в чём разница, если смотреть с точки зрения синтаксиса?

Iska 07-05-2011 22:21 1672153

Цитата:

Цитата shao
А в чём разница, если смотреть с точки зрения синтаксиса? »

Хоть убей, сейчас уже не вспомню, почему я пришёл к именно такому подходу. То ли какие-то приложения требовали обязательно закавычивать аргументы, то ли ещё что-то… Увы, уже не помню.

shao 07-05-2011 23:13 1672176

Цитата:

Цитата Iska
....Увы, уже не помню. »

Я всецело доверяюсь Вашему опыту и знаниям... :)

Iska 07-05-2011 23:37 1672189

Тогда уж, пожалуйста, доверьтесь моему опыту и в таком суждении: «Доверяй, но проверяй» ;).

El Sanchez 08-05-2011 14:06 1672492


Цитата:

Цитата shao
А в чём разница, если смотреть с точки зрения синтаксиса? »

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

batchfile.bat C:\Program Files (x86) - CMD интерпретирует это как передачу в скрипт 3 параметров
%1 будет содержать - C:\Program
%2 будет содержать - Files
%3 будет содержать - (x86)

batchfile.bat "C:\Program Files (x86)" - CMD интерпретирует это как передачу в скрипт 1 параметра
%1 будет содержать - "C:\Program Files (x86)"

... call:ren "%%i" - передача функции :ren 1 параметра %i, содержащего (без)пробельное имя txt-файла
%1 будет содержать - "имя файла.txt"

Все хорошо, переменная определена как единое целое, но теперь %1 содержит в себе нежелательные, искажающие реальное представление значения параметра, двойные кавычки, от которых необходимо избавляться, добавив символ тильды (~) после знака процента (%). Например:
Код:

batchfile.bat "C:\Program Files (x86)"
%~1 будет содержать - C:\Program Files (x86)

Зачем избавляться:
echo %1\Opera - вернет "C:\Program Files (x86)"\Opera. Неправильный путь, теперь представьте, если вместо echo будет команда, работающая с путями, например, Dir.
echo %~1\Opera - вернет C:\Program Files (x86)\Opera. Теперь путь верен, но для команд, работающих с путями (читай - параметрами, содержащими символы пробела), такой путь будет интерпретирован, как передачу команде нескольких параметров, разделенных символом пробела, поэтому снова заключаем все это добро в кавычки:
dir "%~1\Opera"
ren "%~1"

Выводы: "закавычивайте" параметры, передаваемые в скрипт/функцию, даже если параметр не будет содержать пробел или другие спецсимволы; в теле скрипта/функции удалять кавычки из значения переменной, используя тильду (~), даже если параметр передан без помощи двойных кавычек; снова "закавычивать" переменную или комбинацию с ее участием для команд ее использующую, даже если для команды кавычки не нужны.

shao 08-05-2011 17:53 1672610

El Sanchez, спасибо за объяснения! Порой, таких детальных обЪяснений не хватает здесь !

Но получается какая-то фигня у меня , ребята....

Этот код работает на текстовых файлах. Переименовывает отлично.
Код:

@echo off
setlocal

for %%i in (*.XXX) do call:ren "%%i"
goto:eof

:ren
set /a cnt+=1
set "pref=00%cnt%"
set "name=%~n1"

ren "%~1" "%pref:~-2%_%name:~16%%~x1"

Попробовал переименовать видеофайлы(большого веса) - вот тут и нескладуха получается.
Если указываю в конце кода "EXIT"или "EXIT /B" переименовывает все вот так :

Код:

01_.avi
02_.avi
03_.avi
................

Ставлю паузу в конце - переименовывает (по одному при моём участии) правильно.
Но не по порядку следования файлов. А в разброс...

Iska 08-05-2011 18:27 1672629

shao, приведите исходные имена файлов, из которых получаются:
Код:

01_.avi
02_.avi
03_.avi

а также укажите файловую систему того раздела, на котором находятся исходные файлы.

shao 08-05-2011 20:55 1672719

Цитата:

Цитата Iska
приведите исходные имена файлов ........укажите файловую систему..... »

Флешка ! Файловая система FAT32
Блин, на компьютере на харде не додумался это сделать...
Интересно, а разве это может как-то влиять на работу батника ?!!!

Имена файлов:
Код:

Smurfs s01e01 - The Smurf's Apprentice.avi
Smurfs s01e02 - The Smurfette.avi
Smurfs s01e03 - Vanity Fare.avi

и т.д.


Iska 08-05-2011 21:37 1672740

Цитата:

Цитата shao
Флешка ! Файловая система FAT32
Блин, на компьютере на харде не додумался это сделать...
Интересно, а разве это может как-то влиять на работу батника ?!!! »

Влияет. В NTFS, упрощённо говоря, каталог всегда хранится в отсортированном виде. В FAT/FAT32 — в порядке создания файлов в каталоге. Выход — делать в цикле разбор списка файлов, полученных по:
Код:

dir /b /o:n "*.xxx"
Т.е., наподобие [не проверялось!]:
Код:

for /f "tokens=*" %%i in ('dir /b /o:n "*.xxx"') do call…

shao 08-05-2011 22:14 1672767

Спасибо Iska !
Я сейчас не смогу проверить. Завтра....

И ещё : команда " /o:n " , нсколько понимаю сортирует по имени. А что делает команда " /b " ?
Из справки, по ней ничего не понял....

Iska 09-05-2011 00:17 1672855

Условно говоря, отсекает вводную, суммарную и детальную информацию:
читать дальше »
Код:

E:\Песочница\0054>dir
 Том в устройстве E не имеет метки.
 Серийный номер тома: ****-****

 Содержимое папки E:\Песочница\0054

08.05.2011  23:48    <DIR>          .
08.05.2011  23:48    <DIR>          ..
08.05.2011  19:51              326 0001.cmd
08.05.2011  21:39              109 0002.cmd
08.05.2011  21:38              134 0003.cmd
08.05.2011  19:39            5,428 AVZ.vbs
08.05.2011  16:48            5,290 AVZ2.vbs
              5 файлов        11,287 байт
              2 папок  ********** байт свободно


оставляя только имена файлов:
читать дальше »
Код:

E:\Песочница\0054>dir /b
0001.cmd
0002.cmd
0003.cmd
AVZ.vbs
AVZ2.vbs


Причём, при использовании параметра «/s» («включая подкаталоги») имена файлов будут полными:
читать дальше »
Код:

E:\Песочница\0054>dir /b /s
E:\Песочница\0054\0001.cmd
E:\Песочница\0054\0002.cmd
E:\Песочница\0054\0003.cmd
E:\Песочница\0054\AVZ.vbs
E:\Песочница\0054\AVZ2.vbs


shao 09-05-2011 16:32 1673142

Iska, всё получилось !
На харде , фаловая система FAT32 - такой батник:
Код:

@echo off
setlocal

for /f "tokens=*" %%i in ('dir /b /o:n "*.avi"') do call:ren "%%i"
goto:eof

:ren
set /a cnt+=1
set "pref=00%cnt%"
set "name=%~n1"

ren "%~1" "%pref:~-2%_%name:~16%%~x1"

На харде , фаловая система NTFS - такой батник:
Код:

@echo off
setlocal

for %%i in (*.avi) do call:ren "%%i"
goto:eof

:ren
set /a cnt+=1
set "pref=00%cnt%"
set "name=%~n1"

ren "%~1" "%pref:~-2%_%name:~16%%~x1"

Благодарю Вас и El Sanchez, Foreigner, amel27, за помощь !!!

*****************************************************

Если не затруднит - ещё вопросы, пожалуйста:

1. Есть ли принципиальное различие между "exit" и "goto:eof" ?
2. В каких случаях , что лучше указывать ?
3. Достаточно ли только после "FOR" указать окончание ?
4. как грамотнее всего использовать эти команды ?


Спасибо!

Iska 09-05-2011 18:31 1673191

Цитата:

Цитата shao
1. Есть ли принципиальное различие между "exit" и "goto:eof" ? »

Принципиальное различие — «exit» позволяет указать код возврата, который можно получить и обработать в вызывающем пакетном файле.
Цитата:

Цитата shao
2. В каких случаях , что лучше указывать ? »

Я остановился на «exit /b». Некоторые исследования на эту тему можно увидеть в двух классических трудах:
Урок bat-аники
Особенности реализации командного процессора cmd.exe операционных систем WinNT.
Цитата:

Цитата shao
3. Достаточно ли только после "FOR" указать окончание ? »

Вопрос не понятен.

amel27 10-05-2011 07:46 1673496

Цитата:

Цитата Iska
«exit» позволяет указать код возврата, который можно получить и обработать в вызывающем пакетном файле »

GoTo:EOF сохраняет код возврата последней команды, который тоже можно получить и обработать в вызывающем пакетном файле ;)

shao 11-05-2011 11:54 1674177

Цитата:

Цитата Iska
«exit» позволяет указать код возврата, который можно получить и обработать в вызывающем пакетном файле.
»

Цитата:

Цитата amel27
GoTo:EOF сохраняет код возврата последней команды, который тоже можно получить и обработать в вызывающем пакетном файле ;) »

Так , что получается - без разницы , что указывать ?

amel27 11-05-2011 12:03 1674185

Цитата:

Цитата shao
Так , что получается - без разницы , что указывать ? »

- если Вы не собираетесь обрабатывать ошибки - без разницы;
- если результат процедуры зависит всего от одной команды (типа REN), то достаточно GoTo:EOF, но только сразу после неё, иначе другая команда перезапишет код ошибки;
- если результат процедуры зависит от нескольких команд, других условий либо Вы хотите ввести свою нумерацию исключительных ситуаций, то Exit/B.

sov44 28-09-2011 12:02 1761685

Пришло время навести порядок в картинках. Суть в том, что есть многоуровневая структура вложенных папок. В последней папке лежат файлы *.jpg, *.bmp, *.gif Необходимо переименовать файлы по имени папки, в которой они лежат с порядковым номером и соответствующим разрешением.
К примеру, файлы лежат в папке Priroda. На выходе файлы должны переименоваться
Код:

Priroda-1.jpg
Priroda-2.jpg
Priroda-3.jpg
....
Priroda-1.bmp
Priroda-2.bmp
Priroda-3.bmp
...
Priroda-1.gif
Priroda-2.gif
Priroda-3.gif


SendMessage 28-09-2011 15:16 1761799

Цитата:

Цитата sov44
Необходимо переименовать файлы по имени папки, в которой они лежат с порядковым номером и соответствующим разрешением. »

Код:

@echo off

:: Папка, в которой нужно искать
set "sDir=z:\myfolder"

:: Параметрами проставить нужные расширения
for /r "%sDir%" %%a in (.) do call:RenPicture "%%~dpna" bmp jpg gif

goto:eof
 
:RenPicture
if not "%2"=="" (
for /f "tokens=1* delims=:" %%i in (
  'dir "%~1\*.%2" /a-d/b 2^>nul ^| findstr /i/n "\.%2$" 2^>nul'
) do ren "%~1\%%j" "%~n1-%%i.%2" 2>nul
shift /2
goto RenPicture
)


sov44 28-09-2011 16:53 1761857

SendMessage, Спасибо, то, что надо! Если не сложно, поясните его пожалуйста.

Моей фантазии пока хватило на это:
Код:

@Echo Off
SetLocal EnableExtensions

call :1 "*.jpg"
call :1 "*.bmp"
call :1 "*.gif"
exit

:1
set hh=c:\WL
set cnt=0
For /F "Delims=" %%I In ('Dir %hh%\%1 /B /S 2^>nul') Do (
set kk=%%I
call :ren %kk%
)
exit /b

:ren
set /a cnt+=1
for /f "tokens=1,2,3,4,5 delims=\" %%a in ("%kk%") do (
set ddd=%%d
set ooo=%%e
)
ren %ooo% "%ddd%-%Cnt%%~x1"

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

SendMessage 28-09-2011 17:54 1761908

Цитата:

Цитата sov44
Если не сложно, поясните его пожалуйста. »

Попробую:
Код:

for /r "%sDir%" %%a in (.) do call:RenPicture "%%~dpna" bmp jpg gif
Ну эту строчка и так понятна - рекурсивный обход папок, если стоит в множестве точка - перечисляются только папки. В инструкцию RenPicture передаются маршрут обрабатываемой в текущий момент папки и все нужные расширения.
if not "%2"=="" - то есть если параметр не пустой выполняются нужные действия.
for /f "tokens=1* delims=:" %%i in ('dir "%~1\*.%2" /a-d/b 2^>nul ^| findstr /i/n "\.%2$" 2^>nul') - выводятся все файлы с нужным расширением, а команда findstr их пронумеровывает (ключ /n) - на выводе они выглядят примерно так:
Код:

1:fileOne.bmp
2:fileTwo.bmp
3:OtherFile.bmp

Ну и, соответственно, на выходе отпарсенная строка в переменную %%i получает номер, а в переменную %%j - имя файла.
ren "%~1\%%j" "%~n1-%%i.%2" 2>nul - здесь пояснения тоже не очень нужны. %~1 - маршрут папки, %~n1 - имя папки.
shift /2 - сдвиг параметров. То есть - тот, что до этой команды находился в переменной %3, сдвигается в переменную %2, а из %4 в %3. Поскольку у shift стоит ключ /2 - это означает, что сдвиг будет происходить со 2-го параметра, а 1-й останется неизменным. Таким образом для текущей папки перебираются все нужные расширения. После того, как все они обработаются, управление опять переходит к первому for и начинает обрабатываться следующая папка.


Время: 21:15.

Время: 21:15.
© OSzone.net 2001-