группировка предикатов в find

Эта часть "( -name *txt -o -name *html)" меня смущает в коде:

find $HOME \( -name \*txt -o -name \*html \) -print0 | xargs -0 grep -li vpn

Может кто-нибудь объяснить скобки и "-o"? "-o" это команда или параметр? Я знаю, что скобки экранированы "\", но зачем они?


person Léo Léopold Hertz 준영    schedule 12.03.2009    source источник


Ответы (3)


По умолчанию условия в списке аргументов поиска соединяются вместе. Вариант -o означает «или».

Если вы написали:

find $HOME -name \*txt -o -name \*html -print0

тогда нет действия вывода, связанного с именами файлов, заканчивающимися на «txt», поэтому они не будут напечатаны. Группируя параметры имени в круглых скобках, вы получаете файлы «html» и «txt».


Рассмотрим пример:

mkdir test-find
cd test-find
cp /dev/null file.txt
cp /dev/null file.html

В комментариях ниже есть интересный побочный свет по этому поводу. Если бы команда была:

find . -name '*.txt' -o -name '*.html'

затем, поскольку ни для одной из альтернатив не указано явное действие, для обеих альтернатив используется действие по умолчанию -print (не -print0!) и отображаются оба файла. При наличии -print или другого явного действия после одной из альтернатив (но не другой) вступает в силу только альтернатива с действием.

find . -name '*.txt' -print -o -name '*.html'

Это также предполагает, что у вас могут быть разные действия для разных альтернатив. Вы также можете применить другие условия, такие как время модификации:

find . \( -name '*.txt' -o -name '*.html' \) -mtime +5 -print0

find . \( -name '*.txt'  -mtime +5 -o -name '*.html' \) -print0

Первый печатает файлы txt или html старше 5 дней (поэтому он ничего не печатает для примера каталога - файлы старше на несколько секунд); второй печатает файлы txt старше 5 дней или файлы html любого возраста (так что просто file.html). И так далее...

Спасибо DevSolar за его комментарии, которые привели к этому дополнению.

person Jonathan Leffler    schedule 12.03.2009
comment
Эээ... Из вашего комментария к моему ответу я вижу, что круглые скобки кажутся обязательными для SUN, но он отлично работает без них как в Linux (GNU find), так и в AIX (AIX find). Не могли бы вы уточнить, почему именно без них это не сработает? Согласно «мужской находке», скобки имеют приоритет только... - person DevSolar; 12.03.2009
comment
mkdir найти пример; компакт-диск найти-пример; ›файл.txt; ›файл.html; найти . -name '.txt' -o -name '.html' -print; -- в Solaris и GNU, и Solaris "находят" список только file.html. - person Jonathan Leffler; 12.03.2009
comment
Хе... смешно. Я всегда опускаю «-print», так как это действие по умолчанию. Оказывается, если '-print' не указан, печатаются оба файла — только если вы явно зададите '-print', который сильнее связывается с '-name *html' (потому что это AND) и разбивает все выражение. - person DevSolar; 12.03.2009
comment
Давным-давно печать не была по умолчанию, поэтому я обычно использую ее. «-print0» в Q не используется по умолчанию. Я подтверждаю, что без '-print' вы получаете список обоих файлов в моем примере - GNU и Solaris находит. Интересный побочный эффект - спасибо, DevSolar. - person Jonathan Leffler; 12.03.2009

"-о" означает ИЛИ. То есть имя должно заканчиваться на «txt» или «html». Скобки просто группируют два условия вместе.

person Chry Cheng    schedule 12.03.2009

( и ) позволяют группировать параметры поиска для команды find. -o - это оператор "или".

Эта команда find найдет все файлы, оканчивающиеся на «txt» или «html», и передаст их в качестве аргументов команде grep.

person Andy White    schedule 12.03.2009