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

#for-loop #batch-file #ffmpeg

#for-loop #пакетный файл #ffmpeg

Вопрос:

Я сжимаю видео с помощью FFMPEG с помощью однострочного пакетного скриптинга с ЦИКЛОМ FOR. После сжатия я хочу удалить исходный файл.

Этот код отлично выполняет задание сжатия, но исходный файл не удаляется:

 for %%i in (*.mp4) do ffmpeg -i "%%i" -vcodec libx265 -crf 28 "%%~ni"-small.mp4amp;amp;del "%%i"
pause
  

Что я пропустил?

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

Комментарии:

1. Попробуйте выполнить предложение, подобное этому: DO (ffmpeg -i "%%i" -vcodec libx265 -crf 28 "%%~ni-small.mp4" amp;amp; del "%%i")

2. Есть много способов сделать это в дополнение к тому, на который указывает @Squashman. Вы можете использовать «enabledelayedexpansion», чтобы вы могли писать строки, не беспокоясь о том, будут ли они выполнены успешно. Я сам предпочитаю » пакетные функции «. Моя точка зрения? Есть много способов сделать что-то, и вы можете использовать другой метод, если вам нужно больше одной строки.

3. Вам следует улучшить свой способ цитирования, изменить "%%~ni"-small.mp4 на "%%~ni-small.mp4"

4. @Squashman, круглые скобки не должны иметь никакого значения; возможно ffmpeg , устанавливает его код выхода в ненулевое значение, следовательно amp;amp; , не выполняет следующую del команду; для тестирования я бы временно использовал amp; вместо amp;amp;

Ответ №1:

Я бы предположил, что эта методология послужит вам лучше:

 @For /F "EOL=? Delims=" %%G In ('Dir /B /A:-D "*.mp4" ^| ^
 "%__AppDir__%findstr.exe" /IR ".mp4$" ^| ^
 "%__AppDir__%findstr.exe" /IRV "-small.mp4$"'
) Do @If Not Exist "%%~nG-small%%~xG" (
    ffmpeg.exe -i "%%G" -vcodec libx265 -crf 28 "%%~nG-small%%~xG"
    If Not ErrorLevel 1 If Exist "%%~nG-small%%~xG" Del /A /F "%%G")
  

Идея состоит в том, чтобы получить список каталогов всех файлов с .mp4 расширением. Использование первого findstr для исключения любых файлов, которые соответствуют коротким (8.3) именам. Затем он передает их через другой findstr поиск, чтобы исключить любой из тех файлов, которые уже -small добавлены к их базовому имени. Затем он проверяет, чтобы убедиться, что в этом каталоге нет существующих файлов с тем же базовым именем плюс суффикс -small базового имени (предотвращение возможной перезаписи). Если все они проходят, ffmpeg.exe должен быть вызван (при условии ffmpeg.exe , что он находится в текущем каталоге, внутри %PATH% или зарегистрирован как исполняемый файл с указанием его местоположения в реестре). После завершения преобразования скрипт проверяет, что возвращенное ErrorLevel значение было меньше 1 , (чтобы убедиться, что оно прошло успешно), и если да, то существует ли новый файл (с суффиксом -small базового имени). Если это так, он продолжит удаление, используя Del команду.

Если вы хотите повторить попытку, используя условные операторы вместо ErrorLevel , тогда это будет выглядеть так:

 @For /F "EOL=? Delims=" %%G In ('Dir /B /A:-D "*.mp4" ^| ^
 "%__AppDir__%findstr.exe" /IR ".mp4$" ^| ^
 "%__AppDir__%findstr.exe" /IRV "-small.mp4$"'
) Do @If Not Exist "%%~nG-small%%~xG" (
    ffmpeg.exe -i "%%G" -vcodec libx265 -crf 28 "%%~nG-small%%~xG" amp;amp; (
        If Exist "%%~nG-small%%~xG" Del /A /F "%%G"))
  

Ответ №2:

Я просто ставлю ‘/ f’ после DEL, и он отлично выполняет свою работу. Я не знаю, есть ли какие-либо недостатки принудительного удаления, но это работает.

Последняя строка:

 for %%i in (*.mp4) do ffmpeg -i "%%i" -vcodec libx265 -crf 28 "%%~ni"-small.mp4amp;amp;del /f "%%i"
pause
  

Комментарии:

1. Хотя приятно видеть, что вы решили эту проблему, я использовал /F опцию с моей Del командой в предоставленном мной ответе шестнадцать часов назад! В дополнение к этому я улучшил ваш скрипт и объяснил вам методологию, которую он использовал. Есть ли особая причина, по которой вы не приняли его в качестве предпочтительного решения?

2. @Compo Я благодарен за вашу дань уважения, и это определенно лучше, чем мое решение. Но я хотел просто однострочный, который выполняет работу с пониманием того, почему я не могу обойтись без «/ F». Я действительно не обратил особого внимания на то, что вы используете «/ F», потому что весь код слишком сложен для моего понимания. Я пометил ваш ответ как решение.

3. Однострочный код не выполняется быстрее, его труднее читать, и в вашем случае он недостаточно надежен для реального сценария. Я не добавил в свой код ничего, чего там не должно быть, и второй пример тоже однострочный. Я просто разделил длинные строки для удобства чтения.