Questo è molto più bello da risolvere con globbing che 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
Supponiamo ora di non avere file randagi in questa bella struttura. La directory corrente contiene solo le sottodirectory degli artisti e quelle contengono solo le sottodirectory degli album. Quindi possiamo fare qualcosa del genere:
$ diff <(for x in */*/cover.jpg; do echo "$(dirname "$x")" ; done) <(printf "%s\n" */*)
La <(...)
sintassi è la sostituzione del processo di Bash: ti permette di usare un comando al posto di un argomento di file. Ti consente di trattare l'output di un comando come un file. Quindi possiamo eseguire due programmi e prendere il loro diff, senza salvare il loro output in file temporanei. Il diff
programma pensa che funzioni con due file, ma in realtà sta leggendo da due pipe.
Il comando che produce l'input della mano destra in diff
, printf "%s\n" */*
elenca solo le directory degli album. Il comando a sinistra scorre i *.cover
percorsi e stampa i nomi delle loro directory.
Prova:
$ 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
Ah, le directory a/b
e foo/bar
non hanno cover.jpg
.
Ci sono alcuni casi angolari rotti, come quello di default si *
espande a se stesso se non corrisponde a nulla. Questo può essere risolto con Bash's set -o nullglob
.