Мне нужно исключить .git
из моего find
поиска. Чтобы добиться этого, я использую -path ./.git -prune
переключатель:
$ find . -path ./.git -prune -o \( -type f -o -type l -o -type d \) | grep '.git'
./.git
Однако, хотя при этом пропускается содержимое каталога .git, в нем указывается сам каталог. Работает когда добавляю-path ./.git -prune -o -print -a
find . -path ./.git -prune -o -print -a \( -type f -o -type l -o -type d \) | grep '.git'
Зачем это нужно? Я думал, что обе команды должны иметь одинаковый вывод. Второй синтаксис довольно уродлив.
-print
, иначе неявное-print
относится ко всему условиюОтветы:
man
Страницаfind
дает:Таким образом, в первом примере это не так, и
-path ./.git -prune
это не соответствует действительности, и поэтому действие по умолчанию (-print
) не будет вызываться, поэтому строка печатается.источник
Я был озадачен тем, почему
find
команда также печатала обрезанные каталоги , и некоторыми другими запутанными подробностями того, как это-prune
работает, но смог выяснить это на нескольких примерах.Для запуска приведенных ниже примеров создайте следующие каталоги и файлы.
Чтобы создать эту структуру:
Теперь используйте find для поиска каталогов с именем
aa
. Здесь нет проблем.Ищите все каталоги, кроме aa, и мы получим текущий каталог
.
и./bb
, что также имеет смысл.Пока все хорошо, но когда мы используем
-prune
, find возвращает каталог, который мы удаляем, что поначалу меня смутило, потому что я ожидал, что он вернет все остальные каталоги, а не тот, который был удален.Причина, по которой он возвращает удаляемый каталог, объясняется не в
-prune
разделе справочных страниц, как указано в ответе Тимо , а вEXPRESSIONS
разделе:Это означает, что, поскольку выражение совпадает с
aa
именем каталога, выражение будет иметь значение true и будет напечатано, потому что find неявно добавляет a-print
в конце всей команды. Однако это не добавит-print
, если вы намеренно добавили действие-o -print
в конец самостоятельно:Здесь команда find больше НЕ добавляет неявное
-print
, и поэтому каталог, который мы отбрасываем (aa
), не будет напечатан.Итак, наконец, если мы добавим предложение, которое ищет файлы с шаблоном имени файла
file*
после-o
, то вы должны поставить-print
в конце этого второго предложения, как это:Причина, по которой это работает, одна и та же: если вы не поместите a
-print
во второе предложение, то, поскольку нет действия, кроме-prune
действия, find автоматически добавит-print
в конце команды END, в результате чего-prune
предложение напечатает подрезанный каталог:В общем, вам нужно поместить
-print
команду во втором предложении. Если вы поместите его посередине, как это делал оригинальный постер, он не будет работать правильно, потому что удаляемые файлы будут распечатаны немедленно, а во втором предложении не будет возможности выбрать нужные файлы:Так что, к сожалению, оригинальный постер неправильно дал команду выше, поместив ее
-print
в неправильном месте. Это могло бы сработать для его конкретного случая, но в общем случае это не сработало.Есть тысячи людей, которым трудно понять, как
-prune
работает. Страницаfind
man должна быть обновлена, чтобы предотвратить бесконечную путаницу во всем мире по поводу этой команды.источник
find-4.6.0
руководства (Arch Linux ) говорит: «Если все выражение не содержит никаких действий, кроме -prune или -print, -print выполняется для всех файлов, для которых все выражение истинно». Но работает как вы описываете.со
man
страницы,Итак, может быть, вы можете использовать:
Это не будет список
.git
каталогов.чтобы указать имя файла, вы можете сделать так:
Пожалуйста, обратите внимание на
,
запятую оператора.источник
Вот быстрая и грязная альтернатива:
Я просто не могу вспомнить
find
сложный синтаксис ...источник