Решение состоит в том, чтобы связать два теста имен вместе скобками.
Чтобы проиллюстрировать это, давайте рассмотрим каталог с тремя обычными файлами:
$ ls -a
. .. .hidden1 .hidden2 not_hidden
Теперь давайте исходную команду:
$ find . -name ".*" -o -name "*" -exec echo Found {} \;
Found ./not_hidden
Найден только нескрытый файл.
Затем добавим скобки, чтобы сгруппировать две проверки имени вместе:
$ find . \( -name ".*" -o -name "*" \) -exec echo Found {} \;
Found .
Found ./not_hidden
Found ./.hidden1
Found ./.hidden2
Все файлы найдены.
Решение состоит в использовании скобок.
В исходной команде нет оператора между -name "*"
и -exec ... \;
. Следовательно, find
предполагает оператор по умолчанию, которым является логическое И. Поскольку логическое-и связывает сильнее, чем логическое-или (-o
), это означает, что команда интерпретируется как:
find . \( -name ".*" \) -o \( -name "*" -exec echo Found {} \; \)
Это означает, что exec
запускается, только если первый Не удалось выполнить условие имя
.
Для получения дополнительной информации см. раздел ОПЕРАТОРЫ в man find
.
-exec
Давайте попробуем использовать простой -print
:
$ find . -name ".*" -o -name "*" -print
./not_hidden
Как видите, -print
привязан к -имя "*"
с неявным логическим-и, как указано выше.
Но посмотрите, что происходит без указания действия:
$ find . -name ".*" -o -name "*"
.
./not_hidden
./.hidden1
./.hidden2
Здесь найдены все файлы. Причина в том, что в этой версии -o
является единственным оператором.