Как получить входное имя базы в выводе? - PullRequest
2 голосов
/ 07 января 2020
@echo off
set source="%1"

for %%a in (*.wav, *.aac, *.mp3,) do (
    ffmpeg -i "%1" -i "%%a" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "%1_123.mov"
  )

Я получаю DJI_0002.MOV_123.mov , но мне нужно получить DJI_0002_123.mov .

Ответы [ 2 ]

1 голос
/ 07 января 2020

Как правильно ссылаться на аргумент командного файла?

Переменная окружения source вообще не используется в вашем командном файле. Это дополнительно определено неправильно. Лучше было бы set "source=%~1". Откройте командную строку , запустите call /? и прочитайте справку по выводу от начала первой страницы до конца последней страницы.

В окне командной строки выполните следующие две команды:

echo @set source="%1">Test.bat
echo @set source>>Test.bat

Эти две командные строки создают пакетный файл Test.bat с двумя строками:

@set source="%1"
@set source

Запустить следующее в окне командной строки:

Test.bat "Test argument 1.txt"

Вывод:

source=""Test argument 1.txt""

Видно, что случилось. Имя файла Test argument 1.txt, переданное с необходимыми двойными кавычками из-за того, что в имени файла для пакетного файла есть пробелы, присвоенные переменной среды source с двумя дополнительными двойными кавычками.

Следующий запуск в окне командной строки командная строка:

Test.bat "Define & See argument 1.txt"

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

@set source=""Define & See argument 1.txt""

Вывод справки при запуске в окне командной строки cmd /? объясняет на последней странице, что имя файла содержит пробел или один из этих символов &()[]{}^=;!'+,`~ должен быть заключен в двойные кавычки, как это делается при вызове командного файла с необычным именем файла Define & See argument 1.txt. Но при выполнении первой строки амперсанд больше не находится внутри строки аргумента с двойной кавычкой команды SET и по этой причине интерпретируется как оператор AND, как объяснено в ответе на одной строке с несколькими командами, использующими Windows пакетный файл .

Затем запустите следующие три командные строки в окне командной строки:

echo @if "%~1" == "" echo %~nx0 must be called with a file name!^& pause ^& goto :EOF>Test.bat
echo @set "source=%~1">>Test.bat
echo @set source>>Test.bat

Они воссоздают Test.bat со следующим содержимым:

@if "%~1" == "" echo %~nx0 must be called with a file name!& pause & goto :EOF
@set "source=%~1"
@set source

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

Test.bat

Теперь используйте несколько раз клавишу СТРЕЛКА ВВЕРХ , чтобы вернуться из командной строки в буфер командной строки и выполнить эту строку, нажав key RETURN :

Test.bat "Define & See argument 1.txt"

На этот раз сообщение об ошибке не выводится, только строка:

source=Define & See argument 1.txt

Таким образом, видно, что этот код намного лучше не правда ли. См. Также:
Почему после использования команды 'set var = text' в командной строке не выводится строка с 'echo% var%'?

Последний запуск в окне командной строки:

del Test.bat

Теперь должно быть понятно, как ссылаться на аргументы командного файла.


Как ссылаться на имя файла, присвоенное переменной al oop с модификатором?

Запустите в окне командной строки for /?, чтобы получить вывод справки команды Windows FOR и прочитать эту справку от начала первой страницы до конца последней страницы.

Объясняется, как обращаться к переменной l oop с помощью модификатора, например %~nI, чтобы получить, например, только имя файла без пути и без расширения файла. %~n ссылается на подстроку строки, назначенной в настоящее время переменной l oop между

  • последним backsla sh строки, назначенной переменной l oop или начало строки, присваиваемой l oop на нём, не содержащей backsla sh вообще до
  • последняя точка строки, присвоенная переменной l oop или конец строки, назначенный переменной l oop, если точка не содержит точку после последней обратной реакции / начала строки.

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

@echo off
pushd "%~dp0"
for %%I in (*.wav *.aac *.mp3) do echo %%I
popd

Этот пакетный файл выполняется из окна командной строки путем ввода его пути и имени файла с помощью клавиши TAB , как это было объяснено выводом справки при запуске cmd /?.

. вторая командная строка помещает текущий каталог в стек и делает каталог пакетного файла текущим каталогом. Запустите в окне командной строки pushd /? справку по этой команде. Третья командная строка ищет в этом каталоге не скрытые файлы * .wav и * .aa c и * .mp3 и присваивает имя файла без пути переменной l oop I. Для каждой итерации l oop строка, присвоенная переменной l oop I, просто выводится без использования модификатора. Четвертые строки извлекают ранее извлеченный путь к каталогу из стека и устанавливают этот каталог как текущий каталог для восстановления исходного текущего каталога. Запустите в командной строке окно popd /? для получения справки по этой команде.

Затем измените третью строку в пакетном файле, чтобы получить наконец:

@echo off
pushd "%~dp0"
for %%I in (*.wav *.aac *.mp3) do echo File name of %%I is %%~nI
popd

Еще раз запустите пакетный файл из команды окно запроса, просто нажав один раз клавишу СТРЕЛКА ВВЕРХ и следующую клавишу ВОЗВРАТ .

Можно увидеть, как %%~nI изменяет вывод строки без изменений с помощью %%I .


Что такое конечный пакетный файл?

В вопросе не указано, какое имя файла передается в качестве аргумента в пакетный файл. Похоже, должен быть создан один видеофайл, а имя файла, передаваемое в пакетный файл, представляет собой имя файла, содержащего видеоданные, которые должны быть объединены с аудиофайлом, найденным в текущем каталоге, который может быть * .wav или *. aa c или * .mp3 file.

Итак, наконец, измените командный файл еще раз на командные строки, необходимые для этой задачи:

@echo off
if "%~1" == "" echo %~nx0 must be called with a file name!& pause & goto :EOF
pushd "%~dp0"
for %%I in (*.wav *.aac *.mp3) do ffmpeg.exe -i "%~1" -i "%%I" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "%~dpn1_123.mov" & goto MovieCreated
:MovieCreated
popd

Конечно, это также возможно с несколькими аудиофайлы в каталоге пакетного файла для создания нескольких видеофайлов с видео- и аудиоданными в каталоге пакетного файла с именем каждого аудиофайла, используемого для созданного файла mov ie.

@echo off
if "%~1" == "" echo %~nx0 must be called with a file name!& pause & goto :EOF
pushd "%~dp0"
for %%I in (*.wav *.aac *.mp3) do ffmpeg.exe -i "%~1" -i "%%I" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "%%~nI_123.mov"
popd

It Лучше всего указать ffmpeg.exe с полным именем файла, т.е. диск + путь + имя файла + расширение файла, заключенное в двойные кавычки. Тогда cmd.exe не нужно будет искать на каждой итерации l oop для ffmpeg.exe в текущем каталоге и далее во всех каталогах переменной среды PATH.

1 голос
/ 07 января 2020
@echo off
set source="%1"

for %%a in (*.wav, *.aac, *.mp3,) do (
    ffmpeg -i "%1" -i "%%a" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "%~n1_123.mov"
  )

~ n расширяет подстановку, чтобы она равнялась только имени файла, минус расширение. https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490909 (v = тэ chnet .10)

...