Essa é uma das razões pelas quais você nunca usa um loop for
para iterar sobre um comando cuja saída pode conter espaços. Especialmente se essa saída for uma lista de nomes de arquivos que podem conter qualquer , exceto /
e
. Você caiu no pitfall número 1 . Sempre use while
*.mp4a
. Para ter certeza de que funciona com todos os nomes de arquivos, incluindo aqueles com espaços, novas linhas, tabulações, barras invertidas ou qualquer outro caractere estranho, use:
find /home/family/Music -name '*.m4a' -print0 | while IFS= read -r -d '' file; do
ffmpeg -i "$file" -acodec libvorbis -aq 6 -vn -ac 2 "${file%.m4a}.ogg";
done
Explicação
-
Observe que eu citei
find
, o que garante que o bash não irá expandi-lo antes de passá-lo para-print0
. Isso é importante para os casos em que você possui arquivos que correspondem ao glob no diretório atual. -
O
find
, como você provavelmente sabe, faz com que
separe seus resultados comIFS=
while read -r -d '' file
em vez de novas linhas. -
$file
: isso define o caractere do campo de entrada como nada, garantindo que nenhuma divisão de palavras ocorra. -
for file in $(command)
: iterará os resultados, salvando cada um comohelp read
, como-d ''
. As opções são (deread
):-r do not allow backslashes to escape any characters -d delim continue until the first character of DELIM is read, rather than newline
Configurar o delimitador para a string vazia (
-print0
) torna"${file%.mp3}.ogg";
legal com.m4a
. do find. -
.ogg
: é apenas para remover o sufixofoo.ogg
e substituí-lo porfoo.m4a.ogg
, para obter %code% em vez de %code% .
O resto é o mesmo que você tentou, então estou supondo que você entendeu.