Найти каталоги, которые не содержат файл, но ДА другой

У меня довольно большая музыкальная коллекция, и я хотел бы найти каталоги, в которых у меня все еще есть сжатые файлы (* .rar) без обработки. Следовательно, ищите команду, которая перечисляет каталоги, в которых у меня нет * .flac или * .mp3, но присутствует YES * .rar. Отработка найденные примеры в этом посте:

Я пытался:

comm -3 \
    <(find ~/Music/ -iname "*.rar" -not -iname "*.flac" -not -iname "*.mp3" -printf '%h\n' | sort -u) \
    <(find ~/Music/ -maxdepth 5 -mindepth 2 -type d | sort) \
| sed 's/^.*Music\///'

но не работай.

2
задан 13 April 2017 в 15:24

3 ответа

Следующая команда выведет список всех каталогов, которые не содержат файлы .flac или .mp3:

find ~/Music -type d '!' -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.(flac|mp3)$" ' ';' -print

И следующая команда выведет список всех каталогов, которые содержат файлы .rar:

find ~/Music -type d -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.rar$"' ';' -print

Теперь, присоединившись к этим командам, следующая команда выведет список всех каталогов, которые не содержат .flac или .mp3 файлов и которые содержат .rar файлов:

find ~/Music -type d -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.rar$"' ';' \
    '!' -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.(mp3|flac)$" ' ';' -print
0
ответ дан 13 April 2017 в 15:24

Мое предложение:

find . -iname '*.rar' -exec bash -c 'cd "${1%/*}"; 
  shopt -s nullglob; files=(*.flac *.mp3); 
  ((${#files[@]} == 0)) && echo "$1"' _ {} \;

объяснение: для каждого .rar возьмите его базовый каталог, список * .flac и * .mp3, и, если список пуст, выведите имя файла.

0
ответ дан 13 April 2017 в 15:24

Вероятно, есть более элегантный способ сделать это, но наивно я хотел бы

  • Получить список каталогов, содержащих файлы * .rar (с find и sort -u)
  • Получить список каталогов, содержащих файлы * .mp3 и * .flac (также с find)
  • Вычесть этот второй список из первого (используя grep -v)

Итак:

find . -iname '*.rar' -printf '%h\n' | sort -u > lista.txt
find . -iregex '.*\(.mp3\|.flac\)' -printf '%h\n' | sort -u > listb.txt
grep -v -f listb.txt lista.txt

Вы можете сделать это, не прибегая к временным файлам, используя подстановку процессов, как при попытке в вашем вопросе:

grep -v -f <(find . -iregex '.*\(.mp3\|.flac\)' -printf '%h\n' | sort -u) \
<(find . -iname '*.rar' -printf '%h\n' | sort -u)
0
ответ дан 13 April 2017 в 15:24

Другие вопросы по тегам:

Похожие вопросы: