Esto es mucho mejor para resolver con globbing que con find.
$ cd ... # to the directory one level above the album/artist structure
$ echo */*/*.cover # lists all the covers
$ printf "%s\n" */*/*.cover # lists all the covers, one per line
Ahora suponga que no tiene archivos perdidos en esta bonita estructura. El directorio actual contiene solo subdirectorios de artistas, y esos contienen solo subdirectorios de álbumes. Entonces podemos hacer algo como esto:
$ diff <(for x in */*/cover.jpg; do echo "$(dirname "$x")" ; done) <(printf "%s\n" */*)
La <(...)
sintaxis es la sustitución del proceso Bash: le permite usar un comando en lugar de un argumento de archivo. Le permite tratar la salida de un comando como un archivo. Entonces podemos ejecutar dos programas y tomar su diff, sin guardar su salida en archivos temporales. El diff
programa cree que está trabajando con dos archivos, pero en realidad está leyendo desde dos canales.
El comando que produce la entrada a mano derecha diff
, printf "%s\n" */*
, solo muestra los directorios del álbum. El comando de la mano izquierda recorre las *.cover
rutas e imprime sus nombres de directorio.
Prueba de funcionamiento:
$ find . # let's see what we have here
.
./a
./a/b
./foo
./foo/bar
./foo/baz
./foo/baz/cover.jpg
$ diff <(for x in */*/cover.jpg; do echo "$(dirname "$x")" ; done) <(printf "%s\n" */*)
0a1,2
> a/b
> foo/bar
Ajá, los directorios a/b
y foo/bar
no tienen cover.jpg
.
Hay algunos casos de esquina rota, por ejemplo, de forma predeterminada se *
expande a sí mismo si no coincide con nada. Esto se puede solucionar con Bash's set -o nullglob
.