2016-08-16 3 views
1

Рассмотрим эту иерархию:Loop через вложенные папки вложенные папки и выполнить команду на каждом файле последней вложенной

MainFolder\Sub_Folder1\Original_Files\ 
         \Converted_Files\ 
      \Sub_Folder2\Original_Files\ 
         \Converted_Files\ 

Теперь в каждом ...\Original_Files\ Я кучу видео файлов, которые я буду кодировать и сохранять в соответствующий ...\Converted_Files\.

я мог бы сделать это для одной подпапки с этим кодом партии:

@echo off 
set "sourcedir=G:\Animation\Anime\OnePiece\Episodes\Main" 
set "outputdir=G:\Animation\Anime\OnePiece\Episodes\Converted" 

PUSHD "%sourcedir%" 

    for %%F in (*.mkv) DO ffmpeg -i "%%F" -s 640x480 -map 0 -c:v libx265 "%outputdir%\%%F" 

POPD 

Я генерировал текстовый файл с путем к папкам всех подпапок, которая содержит:

G:\Animation\ToConvert\Berserk_1997_The_Complete_Series 
G:\Animation\ToConvert\Blue_Exorcist 
G:\Animation\ToConvert\Elfen_Lied 

Каждой папку перечисленные в файле, имеют Main и Converted папки внутри них. Я должен перебрать все файлы в Main и сохранить в Converted, как вы могли видеть выше.

Это то, что я придумал:

@echo off 
for /F "tokens=*" %%A in (f.txt) DO (
    set "sourcedir=%A%\Main" 
    set "outputdir=%A%\Converted" 
    PUSHD "%sourcedir%" 
     for %%F in (*.mkv) DO ffmpeg -i "%%F" -s 640x480 -map 0 -c:v libx265 "%outputdir%\%%F" 
    POPD 
) %%A 

Запуск for /F "tokens=*" %A in (f.txt) DO @echo %A дает мне имена вложенных папок.

Я как-то подумал, могу ли я передать имя некоторой переменной и объединить \Main и \Converted, это может сработать.

Но при запуске кода из окна командной строки, это просто переключение текущего каталога из папки, в которой я запускаю пакетный файл, до C:\Windows.

Как я могу запустить вложенные петли, один для подпапок, а затем выбрать между работой в Main и сохранить в Converted и следующий цикл для файлов в Main?

+0

Для вашей задачи я хотел бы использовать два вложенные 'для/D' петли для перебора два уровней каталога в основной папке, а затем стандартный' for' цикла для итерирования '* .mkv' файлов .. в вашем последнем скрипте вам нужно [замедленное расширение] (http://ss64.com/nt/delayedexpansion.html), когда вы пишете и читаете одну и ту же переменную в одном блоке кода ... – aschipfl

+0

@aschipfl Можете ли вы поделиться потому что я не знаю пакетного программирования. Все, что я делаю, это поиск в Google и смешивание соответствующих синтаксисов !!!!!! – daddyodevil

ответ

2

Ваша последняя партия код не удается из-

  1. ссылки на цикле переменной A как среды переменных с %A% вместо %%A и
  2. ссылки среда переменных, определенных/установить внутри команды блок, определенный с помощью ( и ), требует использования с задержкой расширения включены ранее с помощью командной строки setlocal EnableDelayedExpansion и используя !sourcedir! и !outputdir! вместо %sourcedir% и %outputdir%, которые уже заменены текущего значения среды переменных sourcedir и outputdir (пустой строкой здесь не определены ранее), когда командный процессор для Windows Анализирует перед выполнением команды За в первый раз.
  3. %%A после закрытия круглой скобки на конце неизвестен для интерпретатора команд Windows и результатов, поэтому в результате пакетной обработки из-за синтаксической ошибки.

Однако лучше, чем ваш код, который требует сначала создания текстового файла с путем к папкам будет использованием следующего кода:

@echo off 
for /D %%D in ("G:\Animation\ToConvert\*") do (
    if exist "%%D\Main\*.mkv" (
     echo Processing %%D ... 
     if not exist "%%D\Converted\*" md "%%D\Converted" 
     for %%I in ("%%D\Main\*.mkv") do (
      ffmpeg.exe -i "%%I" -s 640x480 -map 0 -c:v libx265 "%%D\Converted\%%~nxI" 
     ) 
    ) 
) 

Внешняя ДЛЯ с параметром /D находит только не скрытые подпапки в папке G:\Animation\ToConvert и удерживает в переменной цикла D имя подпапки с полным путем, не заканчивающимся обратным слэшем.

IF Условие проверяет, существует ли в текущей подпапке папка Main с 1 или более файлами * .mkv для обработки. Если это условие истинно,

  • информационное сообщение выводится, чтобы увидеть прогресс в выполнении пакетного файла,
  • в текущей вложенной папки Converted создается, если уже не существует,
  • другой ДЛЯ петли выполняется для обработки каждого * .mkv файла, найденного в папке Main текущей подпапки.

Переменная цикла I содержит имя текущего файла * .mkv с полным путем. Таким образом, "%%I" может использоваться для входного файла, поскольку текущий каталог не имеет значения, поскольку имя входного файла имеет полный путь.

Для выходного файла указанна папка Converted в текущей вложенной папке с добавлением %%~nxI имени файла и расширения файла входного файла в качестве имени для выходного файла.

Этот пакетный код не требует отложенного расширения, так как нет никакой переменной окружения, только переменные цикла D и I.

Для полноты вашего кода с использованием текстового файла, содержащего по строкам, папки для обработки с удалением всех ненужных переменных среды, чтобы можно было запускать командный файл без использования команд setlocal и endlocal.

@echo off 
for /F "usebackq tokens=*" %%A in ("f.txt") do (
    if exist "%%A\Main\*.mkv" (
     echo Processing %%A ... 
     if not exist "%%A\Converted\*" md "%%A\Converted" 
     for %%I in ("%%A\Main\*.mkv") do (
      ffmpeg.exe -i "%%I" -s 640x480 -map 0 -c:v libx265 "%%A\Converted\%%~nxI" 
     ) 
    ) 
) 

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

  • echo /?
  • for /?
  • if /?
  • md /?

КСТАТИ: См this answer и другие ответы, связанные там, если вы хотите, чтобы понять, что задержка экспансии и какие команды setlocal и endlocal здесь не нужны.

+0

Спасибо за ответ, человек работает так, как должен. И, черт возьми, ваш ответ был просто потрясающим, скажете ли вы, где я могу узнать о программном обеспечении Windows Shell или о том, как он называется, как вы? Учитывая, что у меня созданы основные и конвертированные папки, я запускал более простой код, который я даю ниже. Еще раз спасибо. – daddyodevil

+1

Я уверен, что все эксперты по написанию сценариев пакетного сценария начали с чтения (помощь команды, документация, статьи в www) и пробовали, читали больше и пытались больше и так далее, пока не получили опыт написания сценария пакетного сценария. Тестирование каждой строки пакетного сценария должно выполняться, тем не менее, почти всегда, потому что проверка синтаксиса происходит при выполнении сценария, поскольку не существует этапа предварительной обработки и компиляции, например, для C/C++/C# и других языков программирования. SS64 [Индекс A-Z командной строки Windows CMD] (http://ss64.com/nt/) очень полезен для новичков. – Mofi

1

@Mofi написал отличный ответ, оба его кода работают безупречно.Это просто более простая версия, которую я запускаю, потому что условия, проверенные в этой программе, уже выполнены.

@echo off 
for /F "tokens=*" %%A in (f.txt) DO (
     for %%F in (%%A\Main\*.mkv) DO ffmpeg -i "%%F" -s 640x480 -map 0 -c:v libx265 "%%A\Converted\%%~nxF" 
) 
+0

'%% A \ Main \ *. Mkv' на втором цикле __FOR__ должны быть заключены в двойные кавычки, так как в противном случае командный файл завершится с ошибкой по пути папки с 1 или более пробелами или другим критическим символом, таким как' '&() [] {}^=;! '+, '~' 'в пути. – Mofi

+0

@Mofi еще раз спасибо – daddyodevil

Смежные вопросы