Ce problème est beaucoup plus facile à résoudre avec globbing qu'avec 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
Supposons maintenant que vous n'ayez pas de fichiers errants dans cette belle structure. Le répertoire actuel ne contient que des sous-répertoires d'artistes, et ceux-ci ne contiennent que des sous-répertoires d'albums. Nous pouvons alors faire quelque chose comme ceci :
$ diff <(for x in */*/cover.jpg; do echo "$(dirname "$x")" ; done) <(printf "%s\n" */*)
El <(...)
La syntaxe est la substitution du processus de Bash : elle vous permet d'utiliser une commande à la place d'un argument de fichier. Elle vous permet de traiter la sortie d'une commande comme un fichier. Ainsi, nous pouvons exécuter deux programmes, et prendre leur différence, sans sauvegarder leur sortie dans des fichiers temporaires. Le site diff
Le programme pense qu'il travaille avec deux fichiers, mais en fait il lit à partir de deux tuyaux.
La commande qui produit l'entrée droite de diff
, printf "%s\n" */*
ne liste que les répertoires d'albums. La commande de gauche parcourt les répertoires *.cover
et imprime leurs noms de répertoire.
Test de fonctionnement :
$ 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
Aha, le a/b
y foo/bar
n'ont pas de cover.jpg
.
Il y a quelques cas de coin cassé, comme celui par défaut *
s'étend à lui-même s'il ne correspond à rien. Ce problème peut être résolu avec la fonction set -o nullglob
.