Исключить подкаталог, используя find

У меня есть структура каталогов, подобная этой

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

Существует входящая подпапка во всех папках внутри каталога данных. Я хочу получить все файлы из всех папок и подпапок, кроме входящих/входящих и 456/входящих. Я пробовал следующую команду

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

но он работает не так, как ожидалось.

Рави

Ответ 1

Это работает:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

Объяснение:

  • find /home/feeds/data: начать поиск рекурсивно с указанного пути
  • -type f: найти только файлы
  • -not -path "*def/incoming*": не включайте ничего с def/incoming как часть пути
  • -not -path "*456/incoming*": не включайте ничего с 456/incoming как часть его пути

Ответ 2

-name соответствует только имени файла, а не всему пути. Вместо этого вы хотите использовать -path, для частей, в которых вы обрезаете каталоги, например def/incoming.

Ответ 3

Просто ради документации: вам, возможно, придется копать глубже, поскольку есть много созвездий поиска (как и я). Может получиться, что prune является вашим другом, а -not -path не будет делать то, что вы ожидаете.

Итак, это ценный пример из 15 примеров поиска, которые исключают каталоги:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html

Чтобы связать исходный вопрос, исключая, наконец, работало для меня следующим образом:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

Затем, если вы хотите найти один файл и все еще исключать шаблоны, просто добавьте | grep myFile.txt.

Это может зависеть и от вашей версии поиска. Я вижу:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX