Jest to o wiele łatwiejsze do rozwiązania z globowaniem niż z 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
Załóżmy teraz, że w tej ładnej strukturze nie ma zbłąkanych plików. Bieżący katalog zawiera tylko podkatalogi wykonawców, a te zawierają tylko podkatalogi albumów. Następnie możemy zrobić coś takiego:
$ diff <(for x in */*/cover.jpg; do echo "$(dirname "$x")" ; done) <(printf "%s\n" */*)
<(...)
Składnia jest Bash podstawienie proces: to pozwala użyć polecenia zamiast argumentu plikowego. Pozwala traktować dane wyjściowe polecenia jako plik. Możemy więc uruchomić dwa programy i pobrać ich różnice bez zapisywania ich wyników w plikach tymczasowych. diff
Program myśli, że pracuje z dwoma plikami, ale w rzeczywistości jest to odczyt z dwóch rur.
Polecenie to powoduje wejście prawą rękę diff
, printf "%s\n" */*
tylko wymienia katalogi album. Polecenie po lewej stronie wykonuje iterację *.cover
ścieżek i wypisuje nazwy katalogów.
Testowe uruchomienie:
$ 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, a/b
i foo/bar
katalogi nie mają cover.jpg
.
Istnieją przypadki łamania narożników, takie jak to, że domyślnie *
rozwija się do siebie, jeśli nie pasuje do niczego. Można to rozwiązać za pomocą Basha set -o nullglob
.