Проблема Извлечение части пути к файлу внутри for / r - PullRequest
0 голосов
/ 09 января 2019

У меня проблемы с настройкой способа перекодирования набора файлов в подпапках в целевой каталог при сохранении тех же подкаталогов.

Пример:

C: \ massVideoFiles \ Назад в будущее \ BTF.mp4
... \ Властелин колец \ LOTR.mp4

в итоге

C: \ smallVideoFiles \ Назад в будущее \ BTF.mkv
... \ Властелин колец \ 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 \ massVideoFiles \ Назад в будущее \ BTF.mkv

Я ищу

C: \ smallVideoFiles \ Назад в будущее \ BTF.mkv

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Нет способа позволить 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
0 голосов
/ 09 января 2019

Если проблема заключается в попытке удалить все каталоги в дереве из буквы диска, First Directory TO Last Folder, File; - Пример: 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...