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

lev0tsk 01-06-2020 12:47 2923580

Непонятная ошибка при переименовании файлов в цикле
 
Добрый день!

Такая проблема - периодически поступают файлы следующего формата БББЦЦЦЦЦ.dat, их надо переименовывать с увеличением значения "ЦЦЦЦЦ" на определенную величину
Вот такой CMD:

Код:

set "ni=06300"

FOR %%a IN ("TST*.dat") DO call :nn_fnd "%%a"

Exit

:nn_fnd
  set "fname=%~n1"
  set "fnd=%fname:~-8,3%"& set "n1=%fname:~-5%"
  set /a "nn=1%n1% + 1%ni%"
  set "nn=%nn:~1%"
  ren "%~1" "%fnd%%nn%%~x1"
exit /b


Пример списка файлов:

tst00171.dat
tst00172.dat
tst00173.dat
tst00774.dat
tst01575.dat
tst01876.dat
tst05577.dat
tst09478.dat

Всё вроде бы работает, но первый файл переименовывается дважды - первым в цикле (как и должно быть), и перед "tst09478".
После первого раза - tst06471.dat, и потом ещё раз - tst12771.dat
в итоге вся суть идеи теряет смысл...(((

Не пойму, в чем косяк...

Foreigner 01-06-2020 13:53 2923593

Попробуй так
Код:

@echo off
setlocal

set "ni=10"

for %%i in (tst*.dat) do call:ren %%i
goto:eof

:ren
set "fname=%~n1"
set /a val=%fname:tst=1%+%ni%
ren %1 tst%val:~1,9%%~x1


lev0tsk 01-06-2020 15:40 2923599

Цитата:

Цитата Foreigner
Попробуй так »

Аналогично работает - первый файл два раза обрабатывает...((

Проблема решилась - подсмотрел в "Похожих темах" внизу страницы )))

CMD/BAT - [решено] Ошибка в переименовании группы файлов.

Foreigner 01-06-2020 16:12 2923602

Цитата:

Цитата lev0tsk
первый файл два раза обрабатывает »

Тогда не знаю. У меня все отрабатывает корректно.
Из tst00001.dat получаю tst00011, из tst00101.dat -- tst00111.dat, из tst00201.dat -- tst00211.dat и т.д.

Попробуйте перезапустить cmd.exe если ее не закрывали. В вашем батнике нет ограничения области видимости переменных и они после выполнения экспортируются в сессию консоли. Посмотрите переменные командой set

Попробуйте изменить for на
Код:

for /f %%i in ('dir /b tst*.dat') do ...

lev0tsk 01-06-2020 16:43 2923608

Цитата:

Цитата Foreigner
Тогда не знаю. У меня все отрабатывает корректно. »

Погонял Ваш вариант CMD-шника, интересная штука выявилась...
до ni=99 - работает (вроде) корректно
при ni=100 - получается наложение: tst00001 + 100 = tst00101 (второй файл)
а при ni>100 - получается сабж, двойное переименование первого файла. Почему так - кукуй его знает...???

***
Цитата:

Цитата Foreigner
Попробуйте изменить for на »

В итоге я так и сделал (с использованием "dir") - то, что подсмотрел по ссылке в третьем моем сообщении!..)

Foreigner 01-06-2020 16:56 2923612

Цитата:

Цитата lev0tsk
Почему так - кукуй его знает...??? »

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

for /f %%i in ('dir /b /o-n tst*.dat') do..

lev0tsk 01-06-2020 17:10 2923615

Не-е... в том то и дело, что у меня по условию переименования "ni" всегда должно быть больше чем цифровая часть любого из файлов из списка.

А с "dir" нормально работает с любым порядком сортировки, т.к. список файлов создается до начала переименования и более не изменяется.

megaloman 01-06-2020 20:56 2923648

Код:

@Echo Off
        Set "FileIn=Z:\Box_In\tst?????.dat"
        Set /A Plus=6300
       
        For %%f In ("%FileIn%") Do Ren "%%f"  "%%~nxf.~~~"
        For %%f In ("%FileIn%.~~~") Do (
                Set "Name=%%~nf"
                Call :MyRen "%%f" "%%~nf" "%%Name:~0,3%%" "1%%Name:~3,5%%" %Plus%
        )
Exit /B

:MyRen
        Set /A N=%~4+%~5
        Ren %1 "%~3%N:~1%%~x2"
Exit /B 0


megaloman 01-06-2020 21:58 2923650

Если:
Цитата:

Цитата lev0tsk
что у меня по условию переименования "ni" всегда должно быть больше чем цифровая часть любого из файлов из списка »

то можно так:
Код:

@Echo Off
        Set "FileIn=Z:\Box_In\tst?????.dat"
        Set "Plus=06300"
       
        For %%f In ("%FileIn%") Do (
                Set "Name=%%~nf"
                Call :MyRen "%%f" "%%Name:~0,3%%" "%%Name:~3,5%%" "%Plus%"
        )
Exit /B

:MyRen
        If 10%~3 GEQ 10%~4 Exit /B 1
        Set /A N=10%~3+10%~4
        Ren %1 "%~2%N:~2%%~x1"
Exit /B 0

В этом варианте при повторном запуске батника повторной добавки не будет.

DJ Mogarych 02-06-2020 11:39 2923671

Powershell:
Код:

$num = 10

dir "c:\temp\tst*.dat" |% {
Rename-Item $_ -NewName ('tst' + ((($_.basename).substring(3,5) -as [int]) + $num).ToString("00000") + '.dat')
}


Busla 02-06-2020 12:48 2923686

не нужно менять то множество, по которому итерируете

складывайте переименованное в другую директорию

lev0tsk 02-06-2020 14:16 2923702

Спасибо всем откликнувшимся, вопрос решен... даже несколькими способами! )))
Как говорится - выбирай на вкус...

Iska 02-06-2020 19:55 2923761

Цитата:

Цитата Busla
не нужно менять то множество, по которому итерируете »

Менять-то можно, только надо сначала его получить, а потом уже менять полученный набор. Иначе да, интересные фефекты фикции эффекты обеспечены.


Время: 21:38.

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