1

Я использую Debian 8.0 и хотел бы, например, найти каталоги, которые содержат более 1 файла .mkv . Я попробовал это, и это не удалось:

find -type d -exec find {} -name '*.mkv' | wc -l\;

В SuperUser есть аналогичные вопросы и ответы, которые я не смог адаптировать. Это тоже не сработало для меня:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; find '{}' -name '*.mkv' | wc -l" \; |   awk '$NF>=2'

Сообщение об ошибке указывает на синтаксическую ошибку:

bash: -c: line 0: syntax error near unexpected token `('

Причина этого заключается в том, что каталог имеет такое имя:

Directory With Space and (Brackets)

4 ответа4

2

Я мог бы попробовать что-то вроде этого:

 find dirname -type f -name '*.mkv' -print0 | xargs -0 -L 1 dirname | sort | uniq -c | egrep -v '^ *1 ' | sed 's/^ *[0-9]* //'

Команда find выводит имена всех файлов .mkv, затем xargs создает для всех имя каталога, извлекает только имя каталога, сортирует все записи, uniq предоставляет количество повторяющихся строк и с помощью egrep удаляет те, которые имеют только 1 *. MKV файл и, наконец, удалить счетчики с помощью Sed, чтобы предоставить только список каталогов.

Кстати, -print0 используется для того, чтобы имя файла специального символа не вызывало проблем xargs нужен ключ -0 для правильной интерпретации ввода в этом случае. Как отмечено в комментариях, исключением, конечно, является символ новой строки как часть имени файла, с которым я лично не сталкивался. В этом случае xargs нужен ключ -0 для правильной интерпретации ввода.

1

Я бы посоветовал поручить find найти все файлы и распечатать каталог, содержащий каждое совпадение, чтобы вам не пришлось беспокоиться о разборе странных строк. Затем используйте uniq для подсчета дубликатов и awk для фильтрации по первому полю, распечатывая те, которые встречаются более одного раза. например

find . -type f -iname '*.mkv' -printf '%h\n'|sort|uniq -c | awk '$1 > 1'
0

Вроде хак, но вот что я бы сделал:

for dir in $(find . -type d)
do
  if [ $(ls -l "$dir" | grep '\.mkv$' | wc -l) -ge 2 ]
  then
    echo "$dir"
  fi
done

Как это работает:

  1. Найти все подкаталоги текущей директории find . -type d и зациклить их, каждый каталог будет сохранен в переменной dir
  2. Если каталог содержит более 2 mkv файлов, выведите содержимое $dir

Обновление: мой плохой, я забыл более 2-х частей вашего вопроса. Это должно быть исправлено с помощью -ge вместо -eq (выше уже исправлено)!

0

Perl решение

perl -le 'use File::Find; find (sub {if(/\.mkv$/) {$d{$File::Find::dir}++}}, "."); END {for (sort keys %d) {print if $d{$_}>1}};'

Этот код похож на другие. Treewalk (текущего каталога ".") Подсчитывает каталог всякий раз, когда встречается файл .mkv (хранится в хеше% d). После прогулки распечатываются все каталоги с более чем 2 файлами.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .