Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Batch
DF2 :: ФОРУМЫ > Основные форумы > Софт и железо > Программирование / Coding
Axolotl
Не нашел готовой темы. Создал новую.

Такой вопрос. Когда мне нужно обработать все файлы в папке с какой-то командой, то я использую обычную конструкцию FOR - IN - DO
А вот если мне нужно обработать две группы файлов так, что в итоговой команде нужно последовательно соединить файлы из обоих групп - первый с первым, второй со вторым и.т.д.
Как-то это можно же сделать? Или придется уже писать какую-то конструкцию с подстановкой имен/номеров файлов?
Iv
Так на пальцах непонятно, как именно комп должен понять, какой именно файл из второй группы относится к файлу первой группы. Просто номер в списке?
Axolotl
Цитата(Iv @ 28 Dec 2016, 18:05) *
Так на пальцах непонятно, как именно комп должен понять, какой именно файл из второй группы относится к файлу первой группы. Просто номер в списке?

Ну да. Также как и в обычном цикле с одной группой. Просто тут две группы файлов в разных папках. Т.е. вопрос, вероятно, о том, можно ли сделать двойной цикл с двумя for и in, но с одной командой. А если нет, то как данного результата можно как-то иначе добиться в батнике?
tolich
Думаю, этого можно достичь, воспользовавшись вспомогательным файлом и ключом /F.
test.cmd:
Код
@echo off
for /f "delims=| tokens=1,2" %%i in (test.txt) do (
  echo %%i %%j
)
test.txt:
Код
file11|file12
file21|file22
file31|file32
Результат:
Код
$ test.cmd
file11 file12
file21 file22
file31 file32
Axolotl
Если я правильно понял идею, то сперва, получается, нужно этот файл, опять же, сгенерить нужным образом, что возвращает к исходной задачи. Или нет? И, исходя из ответа, двойной цикл значит сделать нельзя?
Тогда, наверное, проще что-то придумать с просто подстановкой имен. Это, правда, уменьшит немного автоматизацию и создаст некоторые ограничения.

Вообще, если подробнее, задача такая. И да, задача не разовая, а регулярная: Есть две папки с группами файлов. Скажем, покадровые анимации. Цели тут могут быть разные - это и соединить отрендеренную отдельно тень, и наложить также срендеренный отдельно слой ambient occlusion, или даже наложить анимрованный геройский флажок на анимированный двеллинг и.т.п
И нужно их обработать каким-то образом, подставляя поочередно программе их имена парами. Причем, в виде отдельных переменных, т.к. синтаксис у итогового скрипта может быть самым разным.
Etoprostoya
Папка cadre, файлы c_XXX.png
Папка shadow, файлы s_XXX.png
Папка out, файлы frame_XXX.png (результат работы)
XXX - трёхзначный номер: 000, 001, ..., 099, 100, ..., 999

//меньше 10 файлов для обработки
FOR /L %a IN (1,1,9) do convert cadre\c_00%a.png + shadow\s_00%a.png out\frame_00%a.png

//меньше 100 файлов для обработки
FOR /L %b IN (1,1,9) DO FOR /L %a IN (1,1,9) DO convert cadre\c_0%b%a.png + shadow\s_0%b%a.png out\frame_0%b%a.png

//меньше 1000 файлов для обработки
FOR /L %c IN (1,1,9) DO FOR /L %b IN (1,1,9) DO FOR /L %a IN (1,1,9) DO convert cadre\c_%c%b%a.png + shadow\s_%c%b%a.png out\frame_%c%b%a.png

Последний (условный) вариант как-то делал для себя. Рипал игру, а там кадры юнитов и кадры теней были в разных файлах.
Axolotl
Ну т.е. все-таки подстановкой имен. Это я вчера тоже уже сделал. Правда другим способом. И с лидирующими нулями (с которыми всегда Макс рендерит) разобрался иначе.
Делал через цикл "if - set - goto", а с нулями разобрался т.н. паддингом, т.е. отбрасыванием первого регистра путем %num:~-4%, а сам цикл шел начинаясь с 10000.


Но погоди. Ты таки используешь двойной и даже тройной цикл. "FOR /L %b IN (1,1,9) DO FOR /L %a IN (1,1,9) DO convert..."
В этом же и был мой вопрос. Я просто не знал как эта конструкция пишется. Нельзя ли в таком случае просто в первый IN вставить обычный (*.png), а во второй с путем ко второй папке (./path/*.png) ?
Или какая-то проблема возникнет? Сейчас попробую
....P.S. А, понял, так нельзя. Он будет не двойной цикл делать, а внутренние циклы, т.е. пытаться каждый с каждым по очереди.
Axolotl
P.S. Фак. Я совсем туплю. Вот что значит пытаться на больную голову делать. В случае если имена в обоих папках одинаковы, то вообще все тупо и не надо генерацией имен заниматься. Можно же просто одним циклом, а второму параметру просто путь подставить. Ну а если имена разные, то уже, видимо, нужно морочится вышеописанными способами. Но все равно удивительно почему нет двойного цикла.
feanor
Вечный вопрос про паузу для батника
теперь и не через пинг

@choice /c:° /d ° /t:20 > nul

в секундах
tolich
А почему не
@choice /d y /t:20 >nul
feanor
потому что y можно и случайно нажать, а знак градуса валиден для команды и в (большинстве) раскладок все-таки отсутствует (а если хочется хардкора, можно чего-нибудь типа старой псевдографики ░, те упыри, которые могут её случайно нажать, пусть получают все, что заслужили)
ну и для /d судя по документации /с таки необходим
вот двоеточие необязательно, можно и просто @choice /c ° /d ° /t:20 > nul
tolich
Не, это /d необходим для /t, иначе непонятно, что делать по таймауту.

Edit: а, ясно, указанный в /d символ должен быть один из тех, что в /c. Но по умолчанию же /c yn, так что явный /c необязателен, если дефолт y или n.

Edit2: примеры в справке:
Код
   CHOICE /?
   CHOICE /C YNC /M "Y - Да, N - Нет, C - Отмена."
   CHOICE /T 10 /C ync /CS /D y
   CHOICE /C ab /M "a" для выбора параметра 1 и "b" для выбора параметра 2.
   CHOICE /C ab /N /M "a" для выбора параметра 1 и "b" для выбора параметра 2.
Третий и четвёртый пример синтаксически неверные, должно быть:
Код
   CHOICE /C ab /M "\"a\" для выбора параметра 1 и \"b\" для выбора параметра 2."
   CHOICE /C ab /N /M "\"a\" для выбора параметра 1 и \"b\" для выбора параметра 2."
Iv
Небольшое вступление:
В последнее время стал меньше читать, но стараюсь больше слушать какой-нибудь полезной информации. Хорошие и интересные подкасты - редкость, но на ютубе довольно много видеолекций, которые можно не смотреть, а в основном - слушать, благо, пока что хожу на работу пешком по довольно тихим местам.

Цель:
Слушать какие-нибудь лекции, презентации, рассказы или обсуждения с Youtube на ходу с телефона. Не то, чтобы мне было жалко траффика, хотя и это тоже, но с аудио банально проще. Не надо опасаться, что вот экран включится или выключится и видео запустится заново, можно удобно проматывать вперед/назад, можно поставить закладку и потом вернуться к этому месту ещё раз и т.д. Правильный аудиоплеер рулит!

Вопрос удобного скачивания с ютуба и закачивания на телефон был решен, но в последнее время ютуб что-то докрутил и любимый FastestTube перестал нормально сохранять в m4a, но другое расширение позволяет удобно скачивать ролики в mp4.

Итого, есть задача:
Хочу сделать возможность извлечения аудиотрека из видеофайла, чаще всего mp4.

Накатал батничек
C:\Iv\Dropbox\Soft\Video\ffmpeg.exe -i "%1" -vn -ar 44100 -ac 2 -ab 192 -f mp3 %~n1.mp3

И прописал его вызов в контекстном меню файлов с расширением mp4, он работает, но получается извлекать музыку только из файлов без пробелов.
Биополимер вместо жгута.mp4 - не работает
БиополимерВместоЖгута.mp4 - работает

Как допилить батник, чтобы он понимал файлы с пробелами? Или есть прога под андроид, которая может качать аудио с ютупа?
Axolotl
Он пытается обработать только первую часть имени до пробела. Т.е. он воспринимает это как два/три и.т.д пришедших параметра, разделенных пробелами. %1 - подставляет первый параметр, %2 - второй и.т.д. %* - подставляет все пришедшие параметры разом.

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

Либо вместо "%1" использовать "%*"
Iv
Цитата(Axolotl @ 27 Jan 2017, 22:04) *
Тебе нужно либо сразу подавать батнику имя файла в кавычках, но тогда, кажется, нужно убрать кавычки из батника, т.е. писать просто %1 (а иначе, скорее всего, будет две пары кавычек)

Нет. Если убрать кавычки, то батник берет только первое слово из имени файла
Какие лекарства придут на смену антибиотикам.mp4 -> Какие

Цитата
Либо вместо "%1" использовать "%*"

Не помогло. Попробовал использовать и вместо "%1" - "%1 %2 %3 %4 %5 %7", тоже не помогло

А, проблема была с отсутствием кавычек на %~n1.mp3
Axolotl
Цитата(Iv @ 28 Jan 2017, 16:09) *
Нет. Если убрать кавычки, то батник берет только первое слово из имени файла
Какие лекарства придут на смену антибиотикам.mp4 -> Какие

Ну да, как я и сказал. Убирать кавычки у %1 (кажется) надо только в том случае, если ты прямо на батник будешь уже подавать имя файла в кавычках: batnik.bat "Какие лекарства придут на смену антибиотикам.mp4" Т.к., по идее, он иначе возьмет слово в двойные кавычки.


Iv
Озадачился ещё одним вопросом.

Есть картинка aniForge.png, где в лист собраны несколько (4*3) кадров анимации движения.
Есть батник
convert %1.png -crop 316x185 -transparent "rgb(0,255,0)" -dispose background out\%%02d.png
convert out\*.png -delay 6 +repage OUT.gif
, который умеет резать такие листы на набор кадров и потом собирать из них анимированную картинку, но ему надо в явном виде указывать размер кадра, это неудобно.

Хочу просто указывать батнику, сколько кадров по горизонтали (4) и по вертикали (3), чтобы он сам посчитал нужный размер кадра.

Есть команда для imagemagic, которая мне выводит размеры листа
identify -format "%wx%h" aniForge.png, где
%w - ширина, а %h - высота

Вот и пытаюсь передать в переменную параметр картинки, чтобы поделить его на кол-во кадров, которое буду передавать в параметре
Расчлененка+.bat aniForge.png 4 3

Как это сделать?
Банальное
SET W=identify -format "%w" aniForge.png
SET H=identify -format "%h" aniForge.png
почему-то работать не хочет
feanor
Но IM умеет резать на нужное число кусков искоропки!
http://www.imagemagick.org/Usage/crop/#crop_equal
Цитата
As of IM v6.5.8-9 you can now add the special '@' flag to the "-crop" argument. This flag tells the "-crop" operator to try its best to equally divide the image into the number of tiles given. For example...
Etoprostoya
Iv
попробуй использовать проценты в crop
https://www.imagemagick.org/Usage/crop/#crop_percent

Или как феанор советует smile2.gif
Iv
Ага, '@' flag сработал, лист распилился на кадры.
Осталось
1. заставить работать команду convert aniForge.png -crop 4x3@ +repage +adjoin out\%d.gif в батнике
convert %1 -crop 4x3@ +repage +adjoin out\0%d.gif - не работает
2. заставить нумеровать получающиеся файлы с ведущим нулем,
feanor
Если чо, в батниках нужно указывать два % (%% )
приду сегодня или завтра домой, посмотрю, что там у меня пилит хероеслендовские спрайтшиты.
Iv
Это я тоже пробовал
md %~n1
convert %%1 -crop 4x3@ +repage +adjoin %~n1\%d.gif


Расчлененка+.bat aniForge.png

d:\Iv\Dropbox\Soft\Grafix\Imagemagick>md aniForge

d:\Iv\Dropbox\Soft\Grafix\Imagemagick>convert %1 -crop 4x3@ +repage +adjoin
aniForge\d.gif
convert.exe: unable to open image `%1': No such file or directory @ error/blob.c
/OpenBlob/2644.
convert.exe: no decode delegate for this image format `%1' @ error/constitute.c/
ReadImage/550.
convert.exe: no images defined `aniForge\d.gif' @ error/convert.c/ConvertImageCo
mmand/3106.
tolich
Два процента, если имеется в виду параметр for (например, вместо %i надо писать %%i). Если же параметр батника (%1), достаточно одного процента. Имя set-переменной берётся в проценты (%PATH%).
Код
md %~n1
convert %1 -crop 4x3@ +repage +adjoin %~n1\%%d.gif
Axolotl
Цитата(Iv @ 16 Feb 2017, 22:33) *
Это я тоже пробовал
md %~n1
convert %%1 -crop 4x3@ +repage +adjoin %~n1\%d.gif


Должно работать. У меня работает. Только таки с одним %. Я уже забыл причины, но именно %1 не работает в батнике с двумя %%. Может потому, что оно для батника и предназначено?

Забавно, что я как раз сегодня днем на форуме Tiled давал совет по кропанью на кусочки именно такой командой blink.gif

А что пишет с одним процентом?

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

md "%~n1"
convert %1 -crop 4x3@ +repage +adjoin "%~n1\%d.gif"
tolich
Цитата(Axolotl @ 16 Feb 2017, 19:04) *
А что пишет с одним процентом?
Видимо, пишет последний кадр в один d.gif, вместо подстановки номера кадра или что там должно быть.
Axolotl
Цитата(tolich @ 16 Feb 2017, 23:09) *
Цитата(Axolotl @ 16 Feb 2017, 19:04) *
А что пишет с одним процентом?
Видимо, пишет последний кадр в один d.gif, вместо подстановки номера кадра или что там должно быть.

Не, IM автоматом нумерует.
Iv
Цитата(Axolotl @ 16 Feb 2017, 19:04) *
Цитата(Iv @ 16 Feb 2017, 22:33) *
Это я тоже пробовал
md %~n1
convert %%1 -crop 4x3@ +repage +adjoin %~n1\%d.gif


Должно работать. У меня работает. Только таки с одним %. Я уже забыл причины, но именно %1 не работает в батнике с двумя %%. Может потому, что оно для батника и предназначено?

Да, в виде convert %1 -crop 4x3@ +repage +adjoin %~n1\%d.png заработало
Спасибо
Iv
Очередной вопрос: как заменить прозрачный фон в кадрах на белый или серый цвет при сборке превью?
Экспериментировал с

md %~n1
convert %1 -crop %2x%3@ +repage +adjoin %~n1\%d.png
mogrify -background white %~n1\*.png
convert %~n1\*.png -delay 6 +repage %~n1.gif

и
convert %~n1\*.png -fill grey -opaque cyan -delay 4 +repage out.gif

не работает
Axolotl
Нужно убрать альфа канал после указания цвета фона -alpha off

mogrify -background white -alpha off %~n1\*.png
Throutle
Не уверен на счёт правильности выбора темы...

Пытаюсь соорудить некий механизм для обеспечения портативности программ (в основном игр). Скрипт или софтина не важно. Может кто знает такое и я зря изобретаю велосипед? Что должно происходить:

- Копирование папки\папок\файла\файлов, лежащих рядом, по нужным местам;
- Импорт ветки\веток\записи\записей реестра;
- Запуск программы и ожидание пока она завершится;
- Копирование папки\папок\файла\файлов обратно и удаление;
- Экспорт ветки\веток\записи\записей реестра обратно и удаление;

В идеале, позже доработать логику обработки коллизий (на случай если по указанным расположениям уже есть файлы\записи), и что бы процесс работы был скрыт от пользователя.

На данный момент пытаюсь сделать это через bat, завёрнутый в vbs:

vbs будет выполняет роль оболочки, для того что бы скрыть окно консоли, как-то так:

Код
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\script.bat" & Chr(34), 1, true
Set WshShell = Nothing

(как запустить bat через относительный путь ещё не смотрел, но думаю это не будет проблемой...)

Копирование в обе стороны (я бы даже сказал синхронизация, т.к. не копирует не изменённое, копирует изменённое и удаляет удалённое) отлично реализуется через:

Код
robocopy "%CD%\folder" "%appdata%\folder" /E /Z /R:3 /W:5 /PURGE

Удаление за собой пока тоже не делал, но и тут проблем быть не должно.

А вот с реестром есть проблемы:

Код
reg import %CD%\registry.reg

Помимо не очень удобного reg как такового, есть совсем большаябеда - без повышения привилегий не хватает прав, а с повышением (что не есть проблема, т.к. вызываться будет из другой программы, лаунчера, и должно отработать наследование повышения привилегий) переменная %CD% отдаёт c:\windows\system32, т.е. расположение cmd.exe, а мне нужен динамический путь к файлу\лам reg =(
t800
Цитата(Throutle @ 30 Apr 2020, 15:46) *
Может кто знает такое и я зря изобретаю велосипед?


Ну мы - к примеру - для игр используем NSIS
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.