Войти

Показать полную графическую версию : [решено] не работает счетчик переименования файлов


Xeruvim4ik
13-04-2013, 19:35
всем привет! помогите со счетчиком в bat-файле. Задача следующая: привести имена файлов к виду name_01.txt, name_02.txt, name_03.txt и тд.
Сам додумался до вот этого.

@echo off
SetLocal EnableDelayedExpansion
for %%t in (*.txt) do (set /a m+=1 rename %%t !m!.txt)

Но работает не так как надо:
1. если файлов не более 37, то имя присваивается
name_1.txt
name_2.txt
.........
name_37.txt

2. как только добавляется 38-й файл, имена присваиваются вот так
name_1.txt
name_10.txt
name_38.txt
........
name_73.txt

3. когда файлов более 100, ситуация для меня еще более странная
name_1.txt
name_10.txt
name_100.txt

Вообщем что-то не так, а вот что не пойму....

zion87
13-04-2013, 20:06
попробуйте так

@echo off
SetLocal EnableDelayedExpansion
for %%t in ("*.txt") do (
set /a m+=1
if !m! LSS 10 ren %%t name_00!m!.txt
if !m! LSS 100 ren %%t name_0!m!.txt
if !m! LSS 1000 ren %%t name_!m!.txt
)

Iska
13-04-2013, 21:07
Я бы вырезал:
@echo off
setlocal enableextensions enabledelayedexpansion

set /a iCount = 1

for %%i in ("*.txt") do (
set sCount=000!iCount!
ren "%%~i" "name_!sCount:~-4!.txt"
set /a iCount += 1
)

endlocal
exit /b 0

megaloman
13-04-2013, 22:58
вместо начального значения счетчика =1 поставил 10001 @echo off
SetLocal EnableExtensions EnableDelayedExpansion

set /a iCount = 10001

For %%i In (*.txt) do ren "%%~i" "name_!iCount:~-4!.txt" && Set /a iCount += 1

Xeruvim4ik
13-04-2013, 23:51
@echo off
SetLocal EnableExtensions EnableDelayedExpansion
set /a iCount = 10001
For %%i In (*.txt) do ren "%%~i" "name_!iCount:~-4!.txt" && Set /a iCount += 1 »

Спасибо! но файлы именуются name_0001.txt, name_0002.txt .......... name_0248.txt
А нужно name_01.txt, name_02.txt .......... name_99.txt, name_0a.txt и т.д.

не совсем понял, что значит iCount:~-4 ?

Iska
14-04-2013, 00:41
megaloman, интересно. Подводных камней (для данного контекста, разумеется) не будет?

не совсем понял, что значит iCount:~-4 ? »

Можно также использовать строки расширения.

%PATH:~10,5%

расширит действие переменной среды PATH, затем использует только 5
символов, которые начинаются с 11-го символа (пропустив 10) расширенного
результата. Если длина не указана, по умолчанию используется оставшееся
значение переменной. Если оба значения (длина и число пропускаемых символов)
отрицательны, следующим используемым значением будет длина значения переменной
среды, добавленной к указанному значению пропуска или указанной длины.

%PATH:~-10%

извлечет последние 10 символов переменной PATH.

%PATH:~0,-2%

извлечет все символы переменной PATH, за исключением 2-х последних.


А нужно name_01.txt, name_02.txt .......... name_99.txt, name_0a.txt и т.д. »
За «99» «0a» не может следовать. За «09» — да, за «99» — ну, никак.

megaloman
14-04-2013, 10:19
Iska, Будет подводный камень: если число файлов >9999. Или если какой-либо файл имеет имя name_xxxx.txt. Наверное лучше всё-таки безусловным образом наращивать счетчик. Или анализировать перед переименованием имена файлов. Но проблема в другом, Xeruvim4ik, похоже, хочет получить шестнадцатиричную нумерацию 01 02 ... 0f 10 11 ... ff, при этом число файлов не более 255. И, самое главное, у меня не получается отобразить и нарастить шестнадцатиричное число, похоже, при присваивании автоматически шестнадцатиричное конвертируется в десятичное:

Set /A iCount = 0xff
Echo %iCount%

Получаем 255

Iska
14-04-2013, 12:10
Iska, Будет подводный камень: если число файлов >9999. »
Ну, это понятно. Равно как и ограничение по разрядности «set /a».

gora
14-04-2013, 16:53
Извините, коллеги. А ни кого не смущает тот факт, что переименование ведется в той же самой папке откуда берутся исходные файлы? Цикл For будет\может повторно перебирать уже переименованные файлы, если они окажутся по алфавиту после обрабатываемых в данный момент...

Xeruvim4ik
14-04-2013, 18:50
За «99» «0a» не может следовать. За «09» — да, за «99» — ну, никак »

Ок, понял. А как сделать тогда чтобы после 09 следовало 0a ?


при этом число файлов не более 255. »
файлов больше 255.... и даже не 256 :)

переименование ведется в той же самой папке »
это не проблема, можно сделать copy или move. Главное получить нужные имена.

Dragokas
14-04-2013, 19:35
Iska прав. Можно перебирать от 1 до FF. 10(10) = 0A(16).

gora, поставил эксперимент. Новые файлы не подхватываются (ставил паузу в цикле, а потом создал пару файлов - до и после алфавита).
Среда внутри скобок выполняется единоразово в новом дочернем потоке cmd /c.

Вариант через недокументированный код возврата (минус: будет работать совсем не быстро). Да и решил использовать Dir.

@echo off
SetLocal EnableExtensions EnableDelayedExpansion

Set SrcFolder=l:\Bash\16X-ren\Test

::rd /Q "%SrcFolder%"& md "%SrcFolder%"& For /L %%C in (1,1,255) do <nul set test=>"%SrcFolder%\%%C"
::pause
Set C=0
For /F "delims=" %%A in ('dir /b /a-D-L "%SrcFolder%\*"') do (
Set /a C+=1
if !C! GTR 255 (echo Too more files& goto ext)
cmd /c exit /b !C!
ren "%SrcFolder%\%%A" "name_!=ExitCode:~-2!.txt"
)
:ext
pause

P.S. Пока писал, не увидел ответа ТС.
Xeruvim4ik, и во что переименовывать файл под номером 256? В 16-ричную математику он не влезает в 2 разряда.
Уточните примерное кол-во файлов. Это критично.

Iska
14-04-2013, 20:49
gora, я это пробовал. В зависимости от условий, получаем либо пропуск в нумерации, либо отлуп вида «файл существует» при переименовании.

megaloman
14-04-2013, 21:34
Итак, Xeruvim4ik хочет иметь файлы вида Name_nn.txt. Если nn -десятичное - это не более 99 файлов, шестнадцатиричное - не более ff (=255) файлов. Можно изобрести, допустим, тридцатьшестьричную :) систему, где в каждом разряде будут символы из набора 0123456789abcdefghijklmnopqrstuvwxyz, но при этом всё равно число файлов не очень большое =1295 (если не просчитался). Вот решение для такой системы @Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

Set Num=0123456789abcdefghijklmnopqrstuvwxyz
Set /A Razrad=36

Set /A NNN=%Razrad%-1
Set /A i=0
Set /A j=0

Set End=_%Time:~0,2%%Time:~3,2%%Time:~6,2%%Time:~9,2%

FOR /F "usebackq delims=" %%f IN (`Dir "*.txt" /B /A:-D`) DO (
Set /A j=!j!+1
If !j! GTR %NNN% Set /A j=0 & Set /A i=!i!+1
If !i! GTR %NNN% GoTo :Eof

Call :Number !i! !j!
Move "%%~f" "Name_!RRR!.txt%End%"
)

FOR /F "usebackq delims=" %%f IN (`Dir "*.txt%End%" /B /A:-D`) DO (
Set NEnd=%%~f
Ren "!NEnd!" "!NEnd:~0,-9!"
)
GoTo :Eof

:Number
Set RRR=!Num:~%1,1!!Num:~%2,1!
GoTo :Eof Длинновато, но вроде бы работает. файлов больше 255.... и даже не 256 Xeruvim4ik, осознайте, что в рамках двух разрядов вы не можете закодировать бесконечное число файлов, поэтому должен быть какой-то верхний предел, либо не требовать, чтобы файлы имели вид Name_nn.txt, а, например, Name_N.txt, где N изменяется от 1 до бесконечности.
Спасибо Gora, похоже, не всё так просто в одной директории, как мне хотелось. Поэтому в этом решении исходные перемещаю сначала в файлы, где к расширению добавляю время запуска батника (время должно быть в формате чч:мм:сс,дд с любыми разделителями), а затем переименовываю в txt

Кстати, если написать Set /A Razrad=16, получим классическую шестнадцатиричную нумерацию от 01 до FF

Xeruvim4ik
15-04-2013, 21:57
megaloman, вы гений, это то, что нужно, я бы до такого никогда не додумался




© OSzone.net 2001-2012