Как исключить подкаталоги определенного каталога из команды поиска?

Я пытаюсь получить список файлов, которые я могу передать wc -l, чтобы получить количество слов для всех из них (не используя wc напрямую, поэтому я могу отфильтровать список файлов перед использованием команды).

Моя структура каталогов примерно такая:

- folder
   - file.php
   - file2.html
   - file3.php
   - folder1
   - folder2a
   - folder3b
   - folder4
- file.php
- file2.php

Я хотел бы исключить некоторые каталоги из моего find, в основном библиотеки и другие вещи, которые я не создавал. Я могу сделать это вручную так:

find /var/www/html/ -type f -not -path "/var/www/html/folder/folder1" -not -path "/var/www/html/folder/folder2a" и т. д.

Тем не менее, раздражает необходимость явно указывать все папки, и список также может измениться в любой момент. Я пытался использовать /* и /** для сопоставления с образцом, но это тоже не работает. Есть ли способ для одного из этих исключений в моей команде find, чтобы я мог исключить все подкаталоги определенного каталога, но не исключить сам этот каталог? (включить его файлы , но не любой из его подкаталогов)?

Вот интуитивное предположение:

find /var/www/html -not -path '/var/www/html/someotherbadfolder' -type f \( ! -path "/var/www/html/folder" -maxdepth 1 \)

Но даже find жалуется на это:

find: warning: you have specified the -maxdepth option after a non-option argument -not, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.

Таким образом, кажется, что maxdepth невозможно объединить в операцию.

Есть много вопросов и ответов об исключении определенных подкаталогов, но не вообще никаких подкаталогов в конкретном подкаталоге.

Мне удалось заставить его работать в одном каталоге с помощью -maxdepth 1, но проблема в том, что это часть исключения более крупной команды, и это не сработало после того, как я запустил полную команду. Потенциально мне может потребоваться исключить определенные подкаталоги, а также любые подкаталоги в нескольких других конкретных подкаталогах.


person InterLinked    schedule 16.08.2020    source источник


Ответы (2)


Просто с находкой:

find /var/www/html -type f -not -path '/var/www/html/folder/*/*'

Оригинальный ответ:

Один взлом может быть grep -v на выходе find:

find /var/www/html/ -type f | grep -v "/var/www/html/folder/.*/" | wc -l
person jeremysprofile    schedule 16.08.2020
comment
Это потрясающе! Мне просто нужно было добавить xargs перед wc, и это сделало то, что я искал. Я думаю, что могу просто передать несколько раз, по одному разу для каждой папки с подкаталогами, которые необходимо исключить, и исключить другие подкаталоги как часть поиска. - person InterLinked; 16.08.2020

Предполагая, что вы специально ищете файлы (т.е. не каталоги):

find /var/www/html -type f -not -path "/var/www/html/folder/*/*"

Это потому что:

  • файлы непосредственно под /var/www/html/folder не являются каталогами, поэтому они не соответствуют пункту -path.
  • каталоги непосредственно под /var/www/html/folder не соответствуют -type f.
  • файлы в подкаталогах /var/www/html/folder должны иметь дополнительные / в пути, чтобы они соответствовали выражению -path.
person root    schedule 16.08.2020
comment
Вы правы, я не проверял этот случай, ответ исправлен. - person root; 16.08.2020