У меня возникли проблемы с настройкой способа перекодирования набора файлов из подпапок в целевой каталог, сохраняя при этом те же подкаталоги.
Пример:
C:\massiveVideoFiles\Back to the future\BTF.mp4
...\Lord of the Rings\LOTR.mp4
завершить
C:\smallVideoFiles\Back to the future\BTF.mkv
...\Lord of the Rings\LOTR.mkv
При перекодировании он должен находиться во временной папке, а затем перемещаться в правильный выходной каталог.
setlocal
setlocal EnableDelayedExpansion
set /p src = "Source Directory"
set /p trg = "Target Directory"
call strLen.cmd %src% len
echo %len%
pause
for /R "%src%" %%f in (*.mp4 *.mkv) do (
REM Trying to remove the source file path and only keep the remaining folder tree
set subpath=%%f:~%len%
cls
echo %subpath%
pause
ffmpeg.exe -y -analyzeduration 99999999999 -probesize 99999999999 -i "%%f" -preset medium -rc vbr_hq -cq 22 -pix_fmt yuv420p -c:a copy -c:s copy -c:v hevc_nvenc "%trg%\temp\%subpath%.mkv"
pause
cls
robocopy /s /mov "%trg%\temp" "%trg%"
pause
cls
rd /q /s "%trg%\temp"
pause
echo off
cls
)
pause
Я просто использовал src и trg с %~pfn.mkv, но результат был
C:\smallVideoFiles\massiveVideoFiles\Back to the future\BTF.mkv
я ищу
C:\smallVideoFiles\Back to the Future\BTF.mkv


Если проблема заключается в попытке удалить все каталоги в дереве с буквы диска, от первого каталога до последней папки, файла; - Пример: C:\smallVideoFiles\ и \Back to the Future\BTF.mkv Тогда это решение, которое вы, возможно, ищете.
Чтобы найти букву диска и первый каталог, мы можем использовать простой цикл с tokens=1,2,3* delims=\. Это будет иметь %%A и %%B, которые будут единственными важными данными, которые нам нужны.
for /f "tokens=1,2,3* delims=\" %%A in ('echo %%~dpi') do (
Set "Drive=%%A\%%B"
)
Для получения последней папки это немного сложнее, но в общем смысле мы будем использовать цикл для сбора только последней папки с помощью %%~nxA.
Set "String=%%~dpi"
Set "String=!String:~0,-1%!"
Set "FileName=%%~nxi"
for %%A in (!String!) do (
set "LastFolder=%%~nxA"
)
Объединив эти строки вместе, мы получим результат вашего нового каталога. Batchfile.bat:
@ECHO OFF
@setlocal EnableDelayedExpansion
set /p src = "Source Directory"
set /p trg = "Target Directory"
call strLen.cmd %src% len
for /R "%src%" %%i in (*.mp4 *.mkv) do (
Echo Original: %%i
Rem | Get Drive Letter & First Dir
for /f "tokens=1,2,3* delims=\" %%A in ('echo %%~dpi') do (
Set "Drive=%%A\%%B"
)
Rem | Get File.Extension & One Dir Back
Set "String=%%~dpi"
Set "String=!String:~0,-1%!"
Set "FileName=%%~nxi"
for %%A in (!String!) do (
set "LastFolder=%%~nxA"
)
Echo New: !Drive!\!LastFolder!\!FileName!
Rem | Continue Code
ffmpeg.exe -y -analyzeduration 99999999999 -probesize 99999999999 -i "%%f" -preset medium -rc vbr_hq -cq 22 -pix_fmt yuv420p -c:a copy -c:s copy -c:v hevc_nvenc "%trg%\temp\%subpath%.mkv"
pause
cls
robocopy /s /mov "%trg%\temp" "%trg%"
pause
cls
rd /q /s "%trg%\temp"
pause
cls
)
pause
Невозможно позволить for /R расширять свою переменную цикла как путь относительно своего корня.
Однако для таких задач я обычно использую xcopy команда вместе с его опцией /L (список, но фактически ничего не копирующий), потому что это возвращает относительные пути, которые затем могут быть добавлены к месту назначения:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Enter data here:
set /P _SOURCE = "Source Directory: "
set /P _TARGET = "Target Directory: "
rem // Change to source directory:
pushd "%_SOURCE%" && (
rem // Change to target directory just to check for existence:
pushd "%_TARGET%" && (
rem // Return from target directory to source directory:
popd
rem /* Loop over the output of `xcopy /L`; since we are in the source directory, `xcopy`
rem returns relative paths of all items prefixed with the source drive letter plus a
rem `:`, which we use as the delimiter for the `for /F` loop: */
for /F "tokens=1* delims=:" %%E in ('
rem/ Place multiple `xcopy` commands here, one per the source mask: ^& ^
xcopy /L /S "*.mp4" "%_TARGET%" ^& ^
xcopy /L /S "*.mkv" "%_TARGET%" ^& ^
rem/
') do (
rem // Skip the (empty) summary lines returned by `xcopy`:
if not "%%F"= = "" (
rem // Do something with the relative path like appending it to the destination:
set "SFILE= %%~fF"
set "TFILE=%_TARGET%\%%F"
rem // Use built full destination path, applying delayed expansion:
setlocal EnableDelayedExpansion
echo(!SFILE! -^> !TFILE!
endlocal
)
)
)
rem // Return to original working directory:
popd
)
endlocal
exit /B
Я думаю, это то, что я ищу. Как новичку в этом вопросе, мне нужно будет найти несколько из этих команд и символов, чтобы полностью понять. Комментарии действительно помогли! Одна вещь, которую я не разъяснил, - это то, что видеофайлы могут быть выгружены в корень подкаталога или вложены в такие папки, как% _SOURCE% \ BTTF.mp4 и% _SOURCE% / StarTrek / Season01 / Episode01.mp4. Если я правильно понимаю, он должен нормально справиться с последним, но пропустит ли первый пример, потому что нет подпапки?
У меня проблемы с запуском нескольких команд внутри блока if not "%% F" == "", но я собираюсь начать новый пост для большей ясности.
Не должно быть разницы, есть ли одна или несколько команд. В любом случае, если вы устанавливаете и читаете одну и ту же переменную внутри этого блока if, убедитесь, что отложенное расширение включен; Я собираюсь расширить свой ответ по этому поводу, потому что я думаю, что это вызывает проблемы, поскольку вы тоже ошиблись в своем вопросе ...
В качестве побочного примечания: вы не можете выполнять расширение подстроки, например
set subpath=%%f:~%len%, в метапеременныхfor, оно работает только для обычных переменных среды ...