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

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Последовательное, циклическое переименование файлов в каталоге по кругу в cmd. (http://forum.oszone.net/showthread.php?t=313609)

Vasylich 07-04-2016 14:40 2623974

Последовательное, циклическое переименование файлов в каталоге по кругу в cmd.
 
Здравствуйте!
Почти не разбираюсь в скриптах, поэтому прошу помощи.
В каталоге есть файлы c числовыми именами: 01.jpg, 02.jpg и т.д.
Нужно переименовывать файлы так, что бы после каждого срабатывания cmd
последний становился первым по порядку цифр, первый вторым, второй - третьим и т.д..
Первоначальное именование по порядку возможно, если будет необходимо для скрипта.
Файлов может быть от 01 до 99.

Спасибо.

Foreigner 07-04-2016 16:41 2624020

Код:

@echo off
setlocal enabledelayedexpansion

for %%i in (*.jpg) do set /a cnt+=1
for %%i in (*.jpg) do (

        set "new=0!cnt!"
        ren "%%i" "!new:~-2!.tmp"
        set /a cnt-=1

)

ren *.tmp *.jpg


Iska 07-04-2016 17:19 2624032

Foreigner, а вдрух у него там FAT32!

Foreigner 07-04-2016 17:25 2624036

Iska, А в чем может возникнуть проблема? Под рукой даже флешки нет проверить

Elven 07-04-2016 17:30 2624039

Foreigner, в именах.

alpap 07-04-2016 17:50 2624049

Vasylich, Переименуютя все сразу в нужном вам порядке с первого запуска:
Код:

@echo off
for /f "delims= eol=" %%a in ('dir /a-d/b "katalog\*.jpg"^|sort /+2147483647') do set /a n+=1& cmd/v/c set "m=0!n!"^& ren "katalog\%%~nxa" "new!m:~-2!%%~xa"
exit /b

.

при следующем запуске, по идее, должно произойти обратное, не проверял.

Iska 07-04-2016 18:24 2624061

Цитата:

Цитата Foreigner
Iska, А в чем может возникнуть проблема? »

В порядке отдачи имён функциями ОС.

На NTFS будет всегда лексикографический, поскольку они так и хранятся в MFT — в виде упорядоченного B+ дерева. На FATx порядок будет соответствовать дате создания файлов:
Код:

H:\04>for /l %i in (5, -1, 1) do @copy nul 0%i.txt
Скопировано файлов:        1.
Скопировано файлов:        1.
Скопировано файлов:        1.
Скопировано файлов:        1.
Скопировано файлов:        1.

H:\04>for %i in (*.txt) do @echo %i
05.txt
04.txt
03.txt
02.txt
01.txt

Ровно то же будет и в WSH, и в PoSH, и в C/C++.

В частности, из-за этого пришлось специально учитывать такую возможность здесь: VBScript & CMD: разделение файла на фрагменты и их последующее слияние — Серый форум. В первом варианте я не сообразил как побороть сие простым способом, и сделал поочерёдное «подклеивание» частей. Затем тутошний коллега Diamond навёл меня на мысль, что достаточно просто предварительно скопировать части в правильном порядке во временную папку, а затем уже смело использовать «copy /b name.ext.part????.bin name.ext» в этой временной папке — ОС будет уже гарантированно отдавать файлы команде copy в нужном порядке (кстати, только сейчас заметил, что описание там в самом скрипте не исправил :)).

Foreigner 07-04-2016 18:41 2624073

Iska, Давно не сталкивался, даже ради интереса создал vhd на fat32 -- действительно сортировка от обратного, тогда лучше через dir + sort (надеюсь, что там не 95)))
Код:

@echo off
setlocal enabledelayedexpansion

for %%i in (*.jpg) do set /a cnt+=1
for /f %%i in ('dir /b *.jpg ^| sort') do (

        set "new=0!cnt!"
        ren "%%i" "!new:~-2!.tmp"
        set /a cnt-=1

)

ren *.tmp *.jpg


Iska 07-04-2016 19:13 2624081

Ну да, тут вполне подойдёт даже и обычный «dir /b /o:n …».

Vasylich 07-04-2016 19:15 2624083

Цитата:

Цитата Foreigner
Код: Выделить весь код
@echo off
setlocal enabledelayedexpansion
for %%i in (*.jpg) do set /a cnt+=1
for %%i in (*.jpg) do (
set "new=0!cnt!"
ren "%%i" "!new:~-2!.tmp"
set /a cnt-=1
)
ren *.tmp *.jpg »

Двойной прогон, правильно я понял?

Foreigner 07-04-2016 19:27 2624085

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

Vasylich 07-04-2016 19:49 2624090

Цитата:

Цитата Foreigner
Vasylich, Каждый запуск зеркально переименовывает файлы »

Зеркально не подойдет. Суть в том, чтобы после каждого срабатывания скрипта последний из списка файл становился 01.jpg, а 01.jpg - 02.jpg и т.д. Т.е. содержимое файлов сдвигалось на 1 по кругу.

Vasylich 07-04-2016 20:08 2624095

А нельзя реализовать простую логику?
1. Находим 01 файл, сохраняем его копию.
2. Переименовываем в цикле пока не достигнет конца шаблон ??.jpg: 02->01, 03->02, 04->03 ... с шагом 1 до последний->предпоследний . Конец цикла.
3. Переименовываем сохранённый в шаге 1 в последний.
Всё.

Foreigner 07-04-2016 20:46 2624108

Код:

@echo off
setlocal enabledelayedexpansion

for /f %%i in ('dir /b /on *.jpg') do set /a cnt=1%%~ni-100

ren 01.jpg 01.tmp

for /l %%i in (2,1,%cnt%) do (

        set "old=0%%i"
        set /a new=%%i-1
        set "new=0!new!"

        ren !old:~-2!.jpg !new:~-2!.jpg

)

set "cnt=0%cnt%"

ren 01.tmp %cnt:~-2%.jpg


Vasylich 07-04-2016 21:02 2624115

Цитата:

Цитата Foreigner
Код: »

Получается нельзя в скрипте найти первый файл без перебора всего списка с помощью dir ?
По всей видимости в ФС файлы хранятся как попало и первый найденный не обязательно 01 и чтобы узнать, какой первый существующий в отсортированном списке нужно получить весь список и отсортировать его?

Foreigner 07-04-2016 21:17 2624117

Цитата:

Цитата Vasylich
Получается нельзя в скрипте найти первый файл без перебора всего списка с помощью dir ? »

Можно. Но если прочтете выше по теме, то на FAT32 результат будет отличаться, поэтому надо сортировать. На NTFS файлы отсортируются сами (по длине строки и посимвольно). Просто попробуйте:
Код:

dir /b *.jpg
на NTFS и на FAT32

Vasylich 07-04-2016 21:27 2624122

Цитата:

Цитата Foreigner
Просто попробуйте: »

Ну на fat32 пока негде попробовать. А там где будет использован скрипт - NTFS.

Foreigner 07-04-2016 21:57 2624134

Тогда dir в данном случае не принципиален.

Vasylich 07-04-2016 22:21 2624146

Цитата:

Цитата Foreigner
Тогда dir в данном случае не принципиален. »

Так а первый for все-равно весь список пройдет..

megaloman 07-04-2016 23:01 2624164

Код:

@Echo off

Set "Where=Z:\kuku"
Set "Mask=*.jpg"

SetLocal EnableExtensions EnableDelayedExpansion
Set "Last=''"

for /f "usebackq delims=" %%i in (`dir "%Where%\%Mask%" /B /O:-N /A:-D 2^>nul`) Do (
        Set "Name=%%i"
        Set /A Num=1!Name:~0,2!+1
        Set "Name=!Name:~2,9999!"
        Ren "%Where%\%%i" "!Num:~1,2!!Name!" 
        If !Last!=='' Set Last=Ren "%Where%\!Num:~1,2!!Name!" "01!Name!"
)
!Last!

Пояснение
Имена файлов могут начинаться от 01 до 99 максимум. Dir c ключом /O:-N сортирует имена файлов по имени в обратном порядке от 99 до 01. Тупо переименовываем все файлы на имя с префиксом на 1 больше. При этом 99, если он был, переименуется в 00, что за пределами диапазона имён. Для самого первого в списке переименованного файла (со старым максимальным номером) запоминаем в переменную команду на переименование его в 01. По завершении цикла запускаем эту команду.
Маску, естественно, можно указать и ??.jpg
Хватает одного цикла и не делается никаких копий.

Foreigner 07-04-2016 23:03 2624165

Цитата:

Цитата Vasylich
Так а первый for все-равно весь список пройдет.. »

И что из этого?

alpap 07-04-2016 23:25 2624170

Vasylich,
Код:

@echo off
setlocal enabledelayedexpansion
for /f "delims= eol=" %%a in ('dir /a-d/b "papka\*.jpg"^|sort /+2147483647') do (
 set /a n+=1& set "nf=%%~na"& set "m=0!n!"
 if !nf:~^,3! neq new (
  ren "papka\%%~nxa" "new!m:~-2!%%~xa"
 ) else (
  ren "papka\%%~nxa" "old!m:~-2!%%~xa"
))
exit /b

.

Iska 08-04-2016 01:51 2624182

Цитата:

Цитата Vasylich
Так а первый for все-равно весь список пройдет.. »

Vasylich, чем Вас это так тревожит? После первого прохода каталог будет кэширован в памяти, повторный опрос будет читать уже из кэша.

Vasylich 08-04-2016 08:23 2624217

Цитата:

Цитата Iska
чем Вас это так тревожит? После первого прохода каталог будет кэширован в памяти, повторный опрос будет читать уже из кэша. »

Ничем :) но вспомнилось, что "краткость - сестра таланта".

Foreigner 08-04-2016 08:38 2624219

Цитата:

Цитата Vasylich
вспомнилось, что "краткость - сестра таланта". »

Погоня за краткостью выливается в полную нечитаемость. Вспомните ТОТ знаменитый однострочник... Когда, помогите, не печатает
http://www.linux.org.ru/forum/development/392747

Vasylich 08-04-2016 08:54 2624225

Цитата:

Цитата Foreigner
Погоня за краткостью выливается в полную нечитаемость. Вспомните ТОТ знаменитый однострочник... Когда, помогите, не печатает
http://www.linux.org.ru/forum/development/392747 »

Согласен. В юности писал на Паскале/С, всегда старался чтобы объектный файл был минимальным и
минимизировал число повторных операций путем замены на логические конструкции. Однако
сильно вырастали пояснения в коде к таким вариантам.

Vasylich 08-04-2016 09:17 2624238

Цитата:

Цитата alpap
Код: Выделить весь код
@echo off
setlocal enabledelayedexpansion
for /f "delims= eol=" %%a in ('dir /a-d/b "papka\*.jpg"^|sort /+2147483647') do (
set /a n+=1& set "nf=%%~na"& set "m=0!n!"
if !nf:~^,3! neq new (
ren "papka\%%~nxa" "new!m:~-2!%%~xa"
) else (
ren "papka\%%~nxa" "old!m:~-2!%%~xa"
))
exit /b »

Работает неправильно. То первый становится последним, то наоборот. А должно быть последовательное движение по кругу.

Vasylich 08-04-2016 11:02 2624281

Цитата:

Цитата megaloman
Код: Выделить весь код
Пояснение »

Код работает как нужно, благодарю!!!

Цитата:

Цитата Foreigner
Код: Выделить весь код
@echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir /b /on *.jpg') do set /a cnt=1%%~ni-100
ren 01.jpg 01.tmp
for /l %%i in (2,1,%cnt%) do (
set "old=0%%i"
set /a new=%%i-1
set "new=0!new!"
ren !old:~-2!.jpg !new:~-2!.jpg
)
set "cnt=0%cnt%"
ren 01.tmp %cnt:~-2%.jpg »

Код работает, задачу решает, хотя и в обратном порядке :) Т.е. "последний" движется в начало.
Благодарю за помощь!

Цитата:

Цитата Foreigner
Код: Выделить весь код
@echo off
setlocal enabledelayedexpansion
for %%i in (*.jpg) do set /a cnt+=1
for /f %%i in ('dir /b *.jpg ^| sort') do (
set "new=0!cnt!"
ren "%%i" "!new:~-2!.tmp"
set /a cnt-=1
)
ren *.tmp *.jpg »

Этот код - не работает. Проблема в логике?

Цитата:

Цитата alpap
Код: Выделить весь код
@echo off
for /f "delims= eol=" %%a in ('dir /a-d/b "katalog\*.jpg"^|sort /+2147483647') do set /a n+=1& cmd/v/c set "m=0!n!"^& ren "katalog\%%~nxa" "new!m:~-2!%%~xa"
exit /b
.
при следующем запуске, по идее, должно произойти обратное, не проверял. »

Код срабатывает правильно первый раз, затем - не работает.

Vasylich 08-04-2016 11:18 2624290

Цитата:

Цитата alpap
Код: Выделить весь код
@echo off
setlocal enabledelayedexpansion
for /f "delims= eol=" %%a in ('dir /a-d/b "papka\*.jpg"^|sort /+2147483647') do (
set /a n+=1& set "nf=%%~na"& set "m=0!n!"
if !nf:~^,3! neq new (
ren "papka\%%~nxa" "new!m:~-2!%%~xa"
) else (
ren "papka\%%~nxa" "old!m:~-2!%%~xa"
))
exit /b »

Это код - не работает.

Foreigner 08-04-2016 11:45 2624309

Цитата:

Цитата Vasylich
Код работает, задачу решает, хотя и в обратном порядке Т.е. "последний" движется в начало. »

Как заказывали, так и работает
Цитата:

Цитата Vasylich
2. Переименовываем в цикле пока не достигнет конца шаблон ??.jpg: 02->01, 03->02, 04->03 ... с шагом 1 до последний->предпоследний »


Vasylich 08-04-2016 11:59 2624318

Цитата:

Цитата Foreigner
Как заказывали, так и работает »

Согласен, сам почему-то так написал :) Но в предыдущем посте писал так:
Цитата:

Цитата Vasylich
Зеркально не подойдет. Суть в том, чтобы после каждого срабатывания скрипта последний из списка файл становился 01.jpg, а 01.jpg - 02.jpg и т.д. Т.е. содержимое файлов сдвигалось на 1 по кругу. »

В любом случае благодарю вас за помощь, ваш код задачу решает !


Время: 04:01.

Время: 04:01.
© OSzone.net 2001-