У меня есть несколько файлов в текущем каталоге,
./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. Я просмотрел справочную страницу поиска и не нашел решения. Другие источники в сети также не дали удовлетворительного объяснения.
-o
не применяется при полном выполнении find
(т. е. «выполните все действия на левой стороне -o
, а если ничего не найдено, выполните правую сторону...)»
Вместо этого -o
— это файл за файлом, что является большой разницей. По сути, у вас есть этот цикл:
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
в одном подвыражении исключает файлы для всех других подвыражений?
На той же странице руководства: the contents of the pruned directories are not even visited, so their contents are irrelevant.
Как уже говорилось, -prune
имеет наивысший приоритет.
«-prune наивысший приоритет», означает ли это, что -prune в одном подвыражении исключает файлы для всех других подвыражений?
спасибо. Я бы хотел, чтобы этот приоритет сокращения был явно указан в руководстве.
Как бы. Поскольку find
выполняет цикл по файлам, а затем применяет выражения, выражение -prune
применяется с приоритетом по отношению к вашим ожиданиям. Выражения будут сокращаться в некоторых выражениях, но не в -prune
. Это может работать так, как вы ожидаете, с выражениями LH и RH, на которые не влияет выражение -prune
.
Это не самый ясный вариант, но я думаю, что он соответствует руководству, ИМХО. Когда парень уровня Эда Мортона говорит, что его это сбивает с толку, это вам о чем-то говорит... Лично я использую -prune
только в 1) не использую логическое выражение (как вы видели, бывают сюрпризы) и 2) в ощущение -prune dragons_be_there
Вы предполагаете, что -prune
означает «не показывать эту запись».
Вместо этого -prune
означает «не заходить в этот каталог».
Каталог верхнего уровня содержит следующее:
./a.txt
./b.txt
./dir1
Если вы используете -prune
, когда встречаете ./dir1
, то find
не опустится в него и, следовательно, никогда не посмотрите на ./dir1/c.txt
или ./dir1/d.txt
.
Возможный дубликат между сайтами: unix.stackexchange.com/questions/276574/…