Isso aconteceria?
find . -name '*.avi' -type f -execdir bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' {} \; -print
Vou tentar explicar como funciona.
Bem, na verdade, é muito fácil: encontrar todos os arquivos no diretório atual, de forma que o nome tenha avi
extension. Para cada um deles, digamos que seja o arquivo X.avi
execute no diretório que está em ( execdir
) o comando:
bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' {}
onde {}
é substituído pelo nome do arquivo, em nosso caso de teste X.avi
. Então isso é como
bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' X.avi
Neste ponto, deixe-me enfatizar que isso é 100% seguro em relação a espaços e outros símbolos engraçados em nomes de arquivos! Agora você vê o trecho que o bash executará? Quero dizer este trecho
f=("${0%avi}"*);((${#f[@]}==1))
Ele será executado com o 0-ésimo parâmetro posicional definido para o nosso nome de arquivo; no nosso exemplo de teste é X.avi
.
A parte "${0%avi}"
expande para o nome do arquivo, com% avi
removido (btw, esse nome de arquivo tem a garantia de ter essa extensão neste ponto) e a parte "${0%avi}"*
será expandida para todos os arquivos no diretório atual (lembre-se, aquele que contém o arquivo) que tem a extensão .avi
. No nosso exemplo de teste, isso é exatamente como:
X.*
Em seguida, criamos uma matriz f
desses e, finalmente, saímos desse processo bash
com êxito se f
contiver apenas um elemento (por isso, muito provavelmente, f
contém apenas X.avi
em nosso exemplo de teste) e falha de outra forma. Se isso foi um sucesso, nós imprimimos o nome do arquivo.