Удаление файлов во вложенных папках после кодирования

#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, поэтому, возможно, ваш скрипт должен запускаться с правами доступа (от имени администратора). Если вам нужна дополнительная помощь в этом, пожалуйста, задайте новый вопрос.