Como outras respostas já foram identificadas, ${f%.*}
é expandido pelo shell antes de executar o comando xargs
. Você precisa que essa expansão aconteça uma vez para cada nome de arquivo, com a variável de shell f
definida para o nome do arquivo (passando -I f
não faz isso: xargs
não tem noção de variável shell, ele procura pela string f
no comando, por isso, se você usou, por exemplo, xargs -I e echo …
, teria executado comandos como ./somedir/somefile.wmacho .mp3
).
Mantendo essa abordagem, informe xargs
para invocar um shell que possa executar a expansão. Melhor, diga que find
- xargs
é uma ferramenta amplamente obsoleta e é difícil de usar corretamente, já que as versões modernas do find possuem uma construção que faz o mesmo trabalho (e mais) com menos dificuldades de encanamento. Em vez de find … -print0 | xargs -0 command …
, execute find … -exec command … {} +
.
find . -name '*.wma' -type f -exec sh -c 'for f; do echo "${f%.*}.mp3"; done' _ {} +
O argumento _
é $0
no shell; os nomes dos arquivos são passados como argumentos posicionais, em que for f; do …
faz um loop. Uma versão mais simples desse comando executa um shell separado para cada arquivo, o que é equivalente, mas um pouco mais lento:
find . -name '*.wma' -type f -exec sh -c 'echo "${0%.*}.mp3"' {} \;
Você não precisa usar find
aqui, presumindo que esteja executando um shell razoavelmente recente (ksh93, bash ≥4.0 ou zsh). No bash, coloque shopt -s globstar
no seu .bashrc
para ativar o padrão **/
glob para recursar em subdiretórios (em ksh, que é set -o globstar
). Então você pode correr
for f in **/*.wma; do
echo "${f%.*}.mp3"
done
(Se você tiver diretórios chamados *.wma
, adicione [ -f "$f" ] || continue
no início do loop).