C'est beaucoup plus agréable à 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 parasites 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. Ensuite, nous pouvons faire quelque chose comme ceci:
$ diff <(for x in */*/cover.jpg; do echo "$(dirname "$x")" ; done) <(printf "%s\n" */*)
La <(...)
syntaxe est la substitution de processus Bash: elle vous permet d'utiliser une commande à la place d'un argument de fichier. Il vous permet de traiter la sortie d'une commande en tant que fichier. Nous pouvons donc exécuter deux programmes et prendre leurs diff, sans enregistrer leur sortie dans des fichiers temporaires. Le diff
programme pense travailler avec deux fichiers, mais en réalité, il lit deux canaux.
La commande qui produit l'entrée de droite dans diff
, printf "%s\n" */*
répertorie simplement les répertoires de l'album. La commande de gauche effectue une itération dans les *.cover
chemins et affiche leurs noms de répertoire.
Essai:
$ 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, les répertoires a/b
et foo/bar
ont pas cover.jpg
.
Il y a des cas de coins cassés, comme celui qui par défaut se *
développe s'il ne correspond à rien. Ceci peut être résolu avec Bash's set -o nullglob
.