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

Aug 15 2020

Я пытаюсь получить список файлов, к которым я могу подключиться, чтобы 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" и т.п.

Однако раздражает необходимость явно указывать все папки, и список может измениться в любой момент. Я пробовал использовать /*и /**для сопоставления с образцом, но это тоже не сработало. Есть ли способ для одного из этих "not" в моей команде 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, но проблема в том, что это часть исключения из более крупной команды, и это не сработало, когда я запустил полную команду. Возможно, мне может потребоваться исключить определенные подкаталоги, а также любые подкаталоги в нескольких других конкретных подкаталогах.

Ответы

jeremysprofile Aug 16 2020 at 01:10

Просто с помощью find:

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
2 root Aug 16 2020 at 01:13

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

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выражению.