Да, я перебираю свою музыку. У меня все прекрасно устроено в следующей мантре: /Artist/Album/Track - Artist - Title.ext
и если она существует, обложка сидит внутри /Artist/Album/cover.(jpg|png)
.
Я хочу просмотреть все каталоги второго уровня и найти те, которые не имеют обложки. Под вторым уровнем я имею в виду, что мне все равно, если /Britney Spears/
не будет cover.jpg, но мне было бы все равно, если бы /Britney Spears/In The Zone/
его не было.
Не беспокойтесь о загрузке обложки (это интересный проект для меня завтра). Меня волнует только великолепный пример с обратным find
примером.
Ответы:
Случай 1: Вы знаете точное имя файла для поиска
Используйте
find
с,test -e your_file
чтобы проверить, существует ли файл. Например, вы ищете каталоги, в которых их нетcover.jpg
:Это чувствительно к регистру, хотя.
Случай 2: Вы хотите быть более гибким
Вы не уверены в случае, и расширение может быть
jPg
,png
...Объяснение:
sh
для каждого каталога, так как при использованииfind
ls -1 "{}"
выводит только имена каталогов, которыеfind
в данный момент проходятegrep
(вместоgrep
) использует расширенные регулярные выражения;-i
делает поиск нечувствительным к регистру,-q
пропускает любой вывод"^cover\.(jpg|png)$"
это шаблон поиска. В этом примере это соответствует, напримерcOver.png
,Cover.JPG
илиcover.png
..
Должно быть экранировано в противном случае это означает , что он соответствует любому символу.^
отмечает начало строки,$
ее конецДругие примеры шаблонов поиска для egrep :
Заменить
egrep -i -q "^cover\.(jpg|png)$"
деталь с:egrep -i -q "cover\.(jpg|png)$"
: Также совпадаетcd_cover.png
,album_cover.JPG
...egrep -q "^cover\.(jpg|png)$"
: Соответствуетcover.png
,cover.jpg
но НЕCover.jpg
(чувствительность к регистру не отключена)egrep -iq "^(cover|front)\.jpg$"
: соответствует, напримерfront.jpg
,Cover.JPG
но неCover.PNG
Для получения дополнительной информации об этом, проверьте Регулярные выражения .
источник
test
?-exec bash -c '[[ -n $(find "{}" -iname "cover.*") ]]' \;
но это довольно грязно с точки зрения оптимизации. Это работает, хотя.test
нагрузку-o EXPRESSION
для запросов ИЛИ ... например:test -e "{}/cover.jpg" -o -e "{}/cover.png"
это лучше, чем полный поиск, но он по-прежнему чувствителен к регистру.$
имя dir (например, Ke $ ha).Просто, это выясняется. Ниже приведен список каталогов с обложкой и сравнение со списком всех каталогов второго уровня. Строки, которые появляются в обоих «файлах», подавляются, оставляя список каталогов, которые нуждаются в обложках.
Ура.
Примечания:
comm
Аргументы следующие:-1
подавить строки, уникальные для file1-2
подавить строки, уникальные для file2-3
подавить строки, которые появляются в обоих файлахcomm
принимает только файлы, отсюда и странный<(...)
метод ввода. Это передает содержимое через настоящий [временный] файл.comm
Нужен отсортированный ввод или он не работает иfind
никоим образом не гарантирует порядок. Это также должно быть уникальным. Перваяfind
операция может найти несколько файлов,cover.*
поэтому могут быть повторяющиеся записи.sort -u
быстро сводит тех к одному. Вторая находка всегда будет уникальной.dirname
это удобный инструмент для получения директории файла без обращения кsed
(и др.)find
иcomm
оба немного запутались с их выводом. Финалsed
здесь, чтобы очистить вещи, чтобы вы остались сArtist/Album
. Это может или не может быть желательным для вас.источник
find
может быть упрощен, чтобыfind ~/Music/ -iname 'cover.*' -printf '%h\n'
избежать необходимостиdirname
. хотяdirname
это удобно в другом месте.Это гораздо приятнее решать с помощью шатания, чем с помощью поиска.
Теперь предположим, что у вас нет случайных файлов в этой хорошей структуре. Текущий каталог содержит только подкаталоги исполнителя, а те содержат только подкаталоги альбома. Тогда мы можем сделать что-то вроде этого:
<(...)
Синтаксис подстановки процесса Bash: она позволяет использовать команду вместо файла аргумента. Это позволяет вам обрабатывать вывод команды как файл. Таким образом, мы можем запустить две программы и взять их разность, не сохраняя их вывод во временных файлах.diff
Программа считает , что она работает с двумя файлами, но на самом деле это чтение из двух труб.Команда , которая производит правильный вход руки в
diff
,printf "%s\n" */*
просто перечисляет альбом каталоги. Левая команда перебирает*.cover
пути и печатает их имена каталогов.Тестовый забег:
Ага, то
a/b
иfoo/bar
каталогов нетуcover.jpg
.Есть несколько случаев с разбитыми углами, например, которые по умолчанию
*
расширяются, если ничего не совпадают. Это можно решить с помощью Башset -o nullglob
.источник
comm
будут чищеdiff
?comm -3 <(printf "%s\n" */*/cover* | sed -r 's/\/[^\/]+$//' | sort -u) <(printf "%s\n" */*)
кажется разумным компромиссом без всякогоdiff
пуха. Это, однако, немного медленнее, чем моя двойная находка.Покажет все каталоги, в которых нет текстовых файлов.
источник