Це набагато приємніше вирішити з глобусом, ніж із знахідкою.
$ 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
Тепер припустимо, у вас немає жодних файлів у цій гарній структурі. Поточний каталог містить лише підкаталоги виконавців, а такі - лише підкаталоги альбомів. Тоді ми можемо зробити щось подібне:
$ diff <(for x in */*/cover.jpg; do echo "$(dirname "$x")" ; done) <(printf "%s\n" */*)
<(...)
Синтаксис Bash підміна процесу: він дозволяє використовувати команду замість файлу аргумент. Це дозволяє розглядати результат команди як файл. Таким чином, ми можемо запустити дві програми та приймати їх різниці, не зберігаючи їх вихід у тимчасових файлах. diff
Програма вважає , що вона працює з двома файлами, але насправді це читання з двох труб.
Команда , яка виробляє правильний вхід руки в diff
, printf "%s\n" */*
просто перераховує альбом каталоги. Команда ліворуч повторює *.cover
контури та друкує їхні назви каталогів.
Пробіг:
$ 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
Ага, a/b
а foo/bar
каталогів немає cover.jpg
.
Є кілька розбитих кутових випадків, наприклад, за замовчуванням *
розширюється до себе, якщо нічого не відповідає. Це можна вирішити за допомогою Баша set -o nullglob
.