Dada a situação em que o áudio precisa ser extraído de arquivos de vídeo que residem em subdiretórios, como alguém faria para nomear adequadamente os arquivos resultantes?
O seguinte one-liner funciona, mas mantém a extensão de arquivo antiga.
find -name "*.mp4" -exec ffmpeg -i {} -vn -acodec copy {}.aac -hide_banner \;
Resultado atual:
foobar.mp4 --> foobar.mp4.aac
Resultado desejado:
foobar.mp4 --> foobar.aac
Não há nenhum mecanismo em
find
si que permita obter uma substring de qualquer coisa que seja substituída por{}
. Mesmo adicionando um sufixo (como você fez:{}.aac
) pode não ser suportado. POSIX disse :Com muitas implementações, coisas como
foo{}bar
funcionam, no entanto, esteja avisado. Para fazer algo mais, você definitivamente precisa de uma ferramenta que manipule a string; geralmente uma casca. No seu caso:Aqui
${1%.*}
é responsável por obter o nome do caminho sem extensão.Você pode ficar tentado a substituir
ffmpeg -i "$1"
porffmpeg -i "{}"
dentro da string de comando passada parash
. Não faça isso. Minha outra resposta explica por que o último está errado (e por quefind . -name …
é melhor quefind -name …
).Outra forma seria:
EDIT: Não tenho ideia de por que pensei em tal loop, quando o mais simples é suficiente:
No entanto, se um recursivo
find
for realmente necessário, com base no comentário de Scott, decidi melhorar a última resposta. Eu uso um loop while com entrada de localização por substituição de processo:Observe que o ffmpeg requer
-nostdin
um loop while. exec e xargs em geral podem ser mais eficientes do que loops while, mas como essa instância faria o ffmpeg fazer o processamento, não sinto que haja um impacto significativo no desempenho.