Назад | Перейти на главную страницу

Найти каталоги, в которых нет каталога?

Я пытаюсь понять, как использовать команду linux «find» (или другую команду, которая выполнит эту работу), чтобы вернуть список путей / каталогов к файлам, которые не содержат каталог с определенным именем.

~/web/domain1.com/public_html/bar
~/web/domain2.com/public_html/
~/web/domain3.com/public_html/bar
~/web/domain4.com/public_html/

Мне нужны все пути, которые не содержат каталог с именем «bar» (domain2.com и domain4.com). Любая идея, как я могу найти для вывода такого списка?

Спасибо!

find ~ -type d '!' -exec test -d '{}/bar' ';' -print

... но, вероятно, это не совсем то, что вам нужно; для приведенных вами примеров каталогов он выведет:

/path/to/home
/path/to/home/web
/path/to/home/web/domain1.com
/path/to/home/web/domain1.com/public_html/bar
/path/to/home/web/domain2.com
/path/to/home/web/domain2.com/public_html
/path/to/home/web/domain3.com
/path/to/home/web/domain3.com/public_html/bar
/path/to/home/web/domain4.com
/path/to/home/web/domain4.com/public_html

т.е. в нем перечислены каждый каталог, который не содержит подкаталог «bar», включая даже сами каталоги «bar» (если они не содержат свои собственные подкаталоги bar ...). Вы, вероятно, захотите добавить дополнительное ограничение, например, только перечисление каталогов на определенной глубине:

find ~ -type d -depth 3 '!' -exec test -d '{}/bar' ';' -print

или с определенным именем:

find ~ -type d -name public_html '!' -exec test -d '{}/bar' ';' -print

... оба печатают:

/path/to/home/web/domain2.com/public_html
/path/to/home/web/domain4.com/public_html

Если вы хотите сопоставить только эти точные каталоги, а не какой-либо экземпляр bar /, тогда подойдет такая команда.

find . \! -wholename '*/web/domain1.com/public_html/bar/*' \
       \! -wholename '*/web/domain1.com/public_html/bar/'  \
       \! -wholename '*/web/domain3.com/public_html/bar/*' \
       \! -wholename '*/web/domain3.com/public_html/bar/'

Если вы хотите игнорировать панель / каталог, в котором каждый из них находится, вам, вероятно, понадобится что-то вроде этого.

find . \! -wholename '*/bar/*' \! -wholename '*/bar/'

Почему бы не использовать grep?

отредактировал:

find . -type d | grep -v "bar"

Это перечислит все каталоги, grep будет читать из стандартного ввода, а затем выполнять обратное сопоставление в строке "bar"

Я не знаю, как использовать find, но это работает:

justin@media:/tmp/sf$ for x in *;do [ -e $x/public_html/bar ] || echo $x;done
domain2.com
domain4.com