Проблема с извлечением части пути к файлу внутри для / r

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

Пример:

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

В качестве побочного примечания: вы не можете выполнять расширение подстроки, например set subpath=%%f:~%len%, в метапеременных for, оно работает только для обычных переменных среды ...

aschipfl 09.01.2019 13:51
В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
0
1
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если проблема заключается в попытке удалить все каталоги в дереве с буквы диска, от первого каталога до последней папки, файла; - Пример: 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. Если я правильно понимаю, он должен нормально справиться с последним, но пропустит ли первый пример, потому что нет подпапки?

Steven S. Smith 09.01.2019 18:34

У меня проблемы с запуском нескольких команд внутри блока if not "%% F" == "", но я собираюсь начать новый пост для большей ясности.

Steven S. Smith 10.01.2019 02:49

Не должно быть разницы, есть ли одна или несколько команд. В любом случае, если вы устанавливаете и читаете одну и ту же переменную внутри этого блока if, убедитесь, что отложенное расширение включен; Я собираюсь расширить свой ответ по этому поводу, потому что я думаю, что это вызывает проблемы, поскольку вы тоже ошиблись в своем вопросе ...

aschipfl 10.01.2019 12:14

Другие вопросы по теме