`find` ведет себя неинтуитивно при обрезке каталогов

У меня есть несколько файлов в текущем каталоге,

./a.txt
./b.txt
./dir1/c.txt
./dir1/d.txt

Когда я выполняю find . -path './dir1' -prune -o -name "*.txt",

как и ожидалось, он исключает все, что находится в каталоге «dir1», и печатает:

./a.txt
./b.txt
./dir1

теперь, если я переключу последовательность подвыражения и выполню find . -name "*.txt" -o -path './dir1' -prune, Насколько я понимаю, оно должно было отображать все файлы, так как подвыражение -name "*.txt" должно было соответствовать всему, что имеет расширение .txt, и просто or их с помощью следующего теста. Поэтому содержимое каталога «dir1» не должно быть исключено. Но, похоже, это не так. Отображаемый результат аналогичен предыдущему.

./a.txt
./b.txt
./dir1

что мне здесь не хватает?

Моя система — Ubuntu-20.04. Я просмотрел справочную страницу поиска и не нашел решения. Другие источники в сети также не дали удовлетворительного объяснения.

Возможный дубликат между сайтами: unix.stackexchange.com/questions/276574/…

tripleee 25.06.2024 17:20
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

-o не применяется при полном выполнении find (т. е. «выполните все действия на левой стороне -o, а если ничего не найдено, выполните правую сторону...)»

Вместо этого -o — это файл за файлом, что является большой разницей. По сути, у вас есть этот цикл:

  1. Найдите файл;
  2. применить все выражения к этому файлу;
  3. ЕСЛИ общее выражение истинно, выполнить действие (по умолчанию print)

Другая вещь, которую здесь происходит, заключается в том, что никакая комбинация -o, -a или круглых скобок не сможет преодолеть то, что -prune имеет наивысший приоритет - если каталог указан с -prune, он никогда не посещается.

Если вы хотите сделать что-то в этом направлении:

find_like . LH_do_first --or RH_do_if_LH_finds_nothing

Тогда Bash, вероятно, ваш лучший выбор. Что-то в этом роде:

lh=$(find . -name "*.txt")
cnt=$(awk '/[^[:blank:]]/{cnt++} END {print cnt}' <<<"$lh")
if (( cnt > 0 )); then 
    printf "%s" "$lh"
else
    find . -path "./dir1" -prune
fi    

на странице руководства я наткнулся на утверждение: «... само действие -prune возвращает true, поэтому следующее -o гарантирует, что правая часть оценивается только для тех каталогов, которые не были сокращены» источник . Это создало у меня впечатление, что отсутствие -prune в LH означает, что все файлы должны быть оценены и вернуть true, если LH или RH истинны. «-удалить наивысший приоритет», означает ли это, что -prune в одном подвыражении исключает файлы для всех других подвыражений?

nabik 25.06.2024 22:49

На той же странице руководства: the contents of the pruned directories are not even visited, so their contents are irrelevant. Как уже говорилось, -prune имеет наивысший приоритет.

dawg 25.06.2024 22:53

«-prune наивысший приоритет», означает ли это, что -prune в одном подвыражении исключает файлы для всех других подвыражений?

nabik 25.06.2024 22:55

спасибо. Я бы хотел, чтобы этот приоритет сокращения был явно указан в руководстве.

nabik 25.06.2024 23:05

Как бы. Поскольку find выполняет цикл по файлам, а затем применяет выражения, выражение -prune применяется с приоритетом по отношению к вашим ожиданиям. Выражения будут сокращаться в некоторых выражениях, но не в -prune. Это может работать так, как вы ожидаете, с выражениями LH и RH, на которые не влияет выражение -prune.

dawg 25.06.2024 23:05

Это не самый ясный вариант, но я думаю, что он соответствует руководству, ИМХО. Когда парень уровня Эда Мортона говорит, что его это сбивает с толку, это вам о чем-то говорит... Лично я использую -prune только в 1) не использую логическое выражение (как вы видели, бывают сюрпризы) и 2) в ощущение -prune dragons_be_there

dawg 25.06.2024 23:10

Вы предполагаете, что -prune означает «не показывать эту запись».

Вместо этого -prune означает «не заходить в этот каталог».

Каталог верхнего уровня содержит следующее:

./a.txt
./b.txt
./dir1

Если вы используете -prune, когда встречаете ./dir1, то find не опустится в него и, следовательно, никогда не посмотрите на ./dir1/c.txt или ./dir1/d.txt.

Другие вопросы по теме