¿Haría esto?
find . -name '*.avi' -type f -execdir bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' {} \; -print
Trataré de explicar cómo funciona.
Bueno, de hecho es muy fácil: encuentra todos los archivos en el directorio actual de modo que el nombre tenga avi
extensión. Para cada uno de estos, digamos que su archivo se X.avi
ejecuta en el directorio en el que está ( execdir
) el comando:
bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' {}
donde {}
se reemplaza por el nombre del archivo, en nuestro caso de prueba X.avi
. Entonces esto es como
bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' X.avi
En este punto, permítanme enfatizar que esto es 100% seguro con respecto a espacios y otros símbolos divertidos en los nombres de archivos ¿Ahora ves el fragmento que bash ejecutará? Me refiero a este fragmento
f=("${0%avi}"*);((${#f[@]}==1))
Se ejecutará con el parámetro posicional 0 a establecido para nuestro nombre de archivo; en nuestro ejemplo de prueba es X.avi
.
La parte se "${0%avi}"
expande al nombre de archivo, con el seguimiento avi
eliminado (por cierto, se garantiza que este nombre de archivo tenga esta extensión en este punto), y la parte "${0%avi}"*
se expandirá a todos los archivos en el directorio actual (recuerde, el que contiene el archivo) que tiene el .avi
extensión. En nuestro ejemplo de prueba, esto es como:
X.*
Luego construimos una matriz a f
partir de estos y, finalmente, salimos de este bash
proceso con éxito si f
contiene solo un elemento (por lo que, muy probablemente, f
solo contiene X.avi
en nuestro ejemplo de prueba), y de lo contrario falla. Si esto fue un éxito, imprimimos el nombre del archivo.