Исключить каталог в find

11

Как я могу найти каждый файл и каталог, соответствующий шаблону, за исключением использования одного каталога find?

Скажем, у меня есть следующая структура файла;

,
  Foo-исключения-я /
    foo.txt
  Foo-исключить меня-не /
    foo.txt
  бар/
    foo.txt
    Foobar /
      bar.txt
      foofoo.txt

как бы получить следующий вывод, используя find:

./bar/foo.txt
./bar/foobar
./bar/foobar/foofoo.txt
./foo-exclude-me-not
./foo-exclude-me-not/foo.txt

Я пытался использовать обе следующие команды:

находить . -name 'foo-exclude-me' -prune -o -name 'foo *'
находить . имя 'foo *' \! -path './foo-exclude-me/*'

но оба они возвращают это:

./bar/foo.txt
./bar/foobar
./bar/foobar/foofoo.txt
./foo-exclude-me # << this should be excluded
./foo-exclude-me-not
./foo-exclude-me-not/foo.txt

Как я могу правильно исключить foo-exclude-meкаталог?

Tyilo
источник
Попробуйте использовать foo-exclude-meвместо ./foo-exclude-me. Также попробуйте добавить -printв конце команды.
n0pe
@MaxMackie perfect :)
Tyilo
Это исправило это? Какое исправление сработало для вас? Я могу поместить это в ответ вместо комментария.
n0pe
@MaxMackie используя оба -printи foo-exclude-meвместо ./foo-exclude-me.
Tyilo
Удивительно, похоже, что Жиль победил меня, хотя :)
n0pe

Ответы:

11
find . -name 'foo-exclude-me' -prune -o -name 'foo*' -print

Если нет -print, неявное действие по умолчанию применяется к каждому совпадению, даже к сокращенным. Явное -printприменяется только при указанных условиях, которые находятся -name 'foo*'только в другой ветви -name 'foo-exclude-me'.

Вообще говоря, используйте явное, -printкогда вы делаете что-то более сложное, чем сочетание предикатов.

Ваша вторая попытка с ! -path './foo-exclude-me/*'не сработала, потому ./foo-exclude-meчто не совпадает ./foo-exclude-me/*(без трейлинга /). Добавление ! -path ./foo-exclude-meбудет работать.

Жиль "ТАК - прекрати быть злым"
источник
-2
-bash-4.1 $ найти. -exec ls -l {} + -name 'a.out' -prune -o -name '*' -exec rm -f {} + -exec ls -l {} +

-rw-р - r--. 1 oradba dba 499 18 января 19:30 ./a.out
-rw-р - r--. 1 oradba dba 499 18 января 20:59 ./b.out
-rw-р - r--. 1 oradba dba 499 18 января 20:59 ./c.out
-rw-р - r--. 1 oradba dba 499 18 января 20:59 ./d.out

.:
всего 16
-rw-р - r--. 1 oradba dba 499 18 января 19:30
-rw-р - r--. 1 oradba dba 499 18 января 20:59 b.out
-rw-р - r--. 1 oradba dba 499 18 января 20:59 c.out
-rw-р - r--. 1 oradba dba 499 18 января 20:59 d.out
rm: не может удалить `. ': каталог
ls: не может получить доступ ./b.out: нет такого файла или каталога
ls: не может получить доступ ./d.out: нет такого файла или каталога
ls: не может получить доступ ./c.out: нет такого файла или каталога
.:
всего 4
-rw-р - r--. 1 oradba dba 499 18 января 19:30

user211226
источник
Использовал опцию prune, чтобы пропустить a.out и работает нормально - art.s
user211226
Вы абсолютно не объясняете, почему -pruneэто актуально. -pruneявляется одним из самых запутанных вариантов find, потому что он отключает -print(который включен по умолчанию)
grochmal
правда истинная; если файл является каталогом, не спускайтесь в него. - Так что он не будет работать в каталогах как защита. - art.s
user211226