Рекурсивно найти все файлы, соответствующие определенному шаблону
Мне нужно найти (или, точнее, подсчитать) все файлы, соответствующие этому шаблону:
*/Foo/*. Документ
Если первая звездочка подстановки содержит переменное количество подкаталогов.
Ответы
Ответ 1
С помощью gnu find вы можете использовать регулярное выражение, которое (в отличие от -name
) соответствует всему пути:
find . -regex '.*/foo/[^/]*.doc'
Чтобы просто подсчитать количество файлов:
find . -regex '.*/foo/[^/]*.doc' -printf '%i\n' | wc -l
(код формата %i
заставляет find
печатать номер inode вместо имени файла, в отличие от имени файла, номер inode, как гарантируется, не имеет символов, таких как новая строка, поэтому подсчет является более надежным. тройка для предложения.)
Я не знаю, будет ли это работать на OSX.
Ответ 2
как насчет:
find BASE_OF_SEARCH/*/foo -name \*.doc -type f | wc -l
Что это делает:
- начать с каталога BASE_OF_SEARCH/
- посмотрите во всех каталогах, у которых есть каталог foo
- искать файлы с именем *.doc
- подсчитать строки результата (по одному на файл)
Преимущество этого метода:
- не рекурсивный, ни итеративный (без циклов)
- его легко читать, и если вы включите его в script, его довольно легко расшифровать (иногда регулярное выражение - нет).
UPDATE: вам нужна переменная глубина? ОК:
find BASE_OF_SEARCH -name \*.doc -type f | grep foo | wc -l
- начать в каталоге BASE_OF_SEARCH
- искать файлы с именем *.doc
- показывают только строки этого результата, которые включают "foo"
- подсчитать строки результата (по одному на файл)
Необязательно, вы можете отфильтровать результаты, имеющие "foo" в имени файла, потому что это тоже покажет их.
Ответ 3
Неподтвержденный, но попробуйте:
find . -type d -name foo -print | while read d; do echo "$d/*.doc" ; done | wc -l
найти все "foo" каталоги (на разных глубинах) (это игнорирует символические ссылки, если та часть проблемы вы можете добавить); используйте shell globbing, чтобы найти все файлы ".doc", а затем подсчитайте их.