#powershell #ffmpeg
#powershell #ffmpeg
Вопрос:
Я хочу удалить файлы в своих вложенных папках с помощью скрипта PowerShell.
Я уже пробовал использовать Remove-Item
в PowerShell, но не смог правильно настроить его…
Это код, который я использую для кодирования:
Get-ChildItem *.mkv | where BaseName -notlike '*`[HEVC]' | foreach {
ffmpeg -i $_ -c:v libx265 -c:a copy -x265-params crf=25 "$($_.BaseName) [HEVC].mkv" -n
}
Я хочу либо включить Remove-Item
[исходный файл] в этот скрипт, чтобы удалить исходные файлы, проверив имя файла.
Как мне это сделать?
Ответ №1:
Сделайте так, чтобы ваш конвейер выводил объекты file-info тех входных файлов, преобразование которых с помощью ffmpeg
было успешным (как подразумевается автоматическим $LASTEXITCODE
выравниванием переменных 0
), и передавал их в Remove-Item
:
Приведенная ниже команда отправляет ffmpeg
вывод (стандартный вывод) только на дисплей, via Write-Host
, чтобы не «загрязнять» конвейер своим стандартным выводом и выводить только объекты file-info; альтернативой является простое подавление ffmpeg
вывода (сообщения об ошибках все еще печатаются): $null = ffmpeg ...
:
Get-ChildItem *.mkv | where BaseName -notlike '*`[HEVC]' | foreach {
# Convert the input file and send ffmpeg's output to the display,
# by piping to Write-Host, rather than trough the pipeline.
ffmpeg -i $_ -c:v libx265 -c:a copy -x265-params crf=25 "$($_.BaseName) [HEVC].mkv" -n |
Write-Host
# Conversion OK? Output the file-info object, which pipes it to Remove-Item.
if ($LASTEXITCODE -eq 0) { $_ }
} | Remove-Item -WhatIf
Примечание: -WhatIf
общий параметр в приведенной выше команде выполняет предварительный просмотр операции. Удалите -WhatIf
, как только убедитесь, что операция выполнит то, что вы хотите.
Примечание: Поскольку Write-Host
в PowerShell версии 5 или выше запись выполняется в информационный поток (номер потока 6
), который по умолчанию отображается на дисплее, все еще возможно перехватить ffmpeg
вывод изнутри PowerShell, а именно с помощью перенаправления 6>amp;1
; в отличие от этого, вызывающий объект извне PowerShell (например, пакетный файл) получаетдаже Write-Host
вывод напрямую через стандартный вывод.
В PowerShell 7 вы можете упростить код внутри foreach
цикла с помощью amp;amp;
конвейерной цепочки и оператора (его дополнительный оператор OR (else) является ||
):
# (Details of the ffmpeg command omitted for brevity).
... | foreach {
# The RHS of amp;amp; is only executed if the command on the LHS succeeded,
# which in the case of external programs means: $LASTEXITCODE equals 0.
ffmpeg $_ ... | Write-Host amp;amp; $_
} | ...
Комментарии:
1. если некоторые файлы не удаляются при этом, поможет ли добавление -f после Remove-Item ?
2. @WorldTeacher: это может помочь, но только в том случае, если у этих файлов установлен атрибут только для чтения (и они все еще не используются другим процессом).
3. Я попытался использовать предоставленный вами скрипт как автономный, который работал нормально, но когда я начал использовать его в своем основном скрипте, который вызывает скрипт для запуска в папке, я получил сообщение об ошибке, в котором говорится, что у меня нет необходимых разрешений. Есть идеи относительно того, как это исправить?
4. @WorldTeacher: Это звучит как проблема с правами доступа к файловой системе, не связанная с PowerShell, поэтому, возможно, ваш скрипт должен запускаться с правами доступа (от имени администратора). Если вам нужна дополнительная помощь в этом, пожалуйста, задайте новый вопрос.