Как использовать опцию' - prune ' из 'find' в sh?



Я не совсем понимаю пример, приведенный из "man find", может ли кто-нибудь дать мне некоторые примеры и объяснения? Могу ли я объединить регулярное выражение в нем?





более подробный вопрос выглядит так: напишите сценарий оболочки, changeall, который имеет интерфейс типа "changeall [-r|-R] "string1" "string2". Он найдет все файлы с суффиксом .ч. ,С, .CC или .cpp и измените все вхождения " string1 "на"string2". - r-это вариант для пребывания только в текущем dir Примечание: 1) для нерекурсивного случая " ls "не допускается, мы могли бы использовать только "find" и "sed". 2) я попытался "найти глубину", но это не было поддержано. Вот почему мне было интересно, может ли "- prune "помочь, но не понял пример из "man find".





EDIT2: я делал задание, я не задавал вопрос в деталях, потому что я хотел бы закончить его сам. Поскольку я уже сделал это и сдал его, теперь я могу сформулировать весь вопрос. Кроме того, мне удалось чтобы закончить задание без чернослива, но хотелось бы все равно узнать его.

929   8  

8 ответов:

то, что я нашел запутанным о о -prune заключается в том, что это действие (например,-print), а не испытание (как -name). Он изменяет список "дел",но всегда возвращает true.

общий шаблон для использования -prune это:

find [path] [conditions to prune] -prune -o \
                                   [your usual conditions] [actions to perform]

вы в значительной степени всегда хотите the -o сразу после -prune, потому что это первая часть теста (до включения -prune) возвращает ложные для чего вы на самом деле хотите (т. е.: то, что вы не хотите обрезать).

вот пример:

find . -name .snapshot -prune -o -name '*.foo' -print

это найдет "*.ФОО" файлы, которые не находятся под ".моментальный снимок" каталоги. В этом примере -name .snapshot это "тесты на материал, который вы хотите обрезать", и -name '*.foo' -print это "материал, который вы обычно ставите после пути".

важная информация:

  1. если все вы хотите сделать, это распечатать результаты можно было выходить элемент -print действие. Ты вообще не хотите сделать это при использовании -prune.

    поведение по умолчанию find является "и"весь выражение -print действие, если нет других действий, кроме -prune (иронично) в конце. Это означает, что написание этого:

    find . -name .snapshot -prune -o -name '*.foo'              # DON'T DO THIS
    

    эквивалентно написанию этого:

    find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
    

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

    find . -name .snapshot -prune -o -name '*.foo' -print       # DO THIS
    
  2. если ваше" обычное состояние " совпадает с файлами, которые также соответствуют вашему состоянию чернослива, эти файлы будут не быть включены в выходные данные. Способ исправить это-добавить -type d предикат для вашего состояния чернослива.

    например, предположим, что мы хотели вырезать любой каталог, который начинался с .git (это, по общему признанию, несколько надуманно - обычно вам нужно только удалить вещь с именем ровно.git), но кроме этого хотел видеть все файлы, в том числе такие файлы, как .gitignore. Вы можете попробовать это:

    find . -name '.git*' -prune -o -type f -print               # DON'T DO THIS
    

    это не включить .gitignore на выходе. Вот исправленная версия:

    find . -type d -name '.git*' -prune -o -type f -print       # DO THIS
    

дополнительный совет: если вы используете версию GNU find, страница texinfo для find подробнее подробное объяснение, чем его manpage (как это верно для большинства утилит GNU).

будьте осторожны-чернослив не мешает спускаться в любой каталог, как некоторые сказали. Он предотвращает спуск в каталоги, соответствующие тесту, к которому он применяется. Возможно, некоторые примеры помогут (см. Внизу пример регулярного выражения). К сожалению для этого быть таким длительным.

$ find . -printf "%y %p\n"    # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh

$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test

$ find . -prune
.

$ find . -name test -prune
./test
./dir1/test
./dir2/test

$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl

$ find . -name test -prune -regex ".*/my.*p.$"
(no results)

$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test

$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py

$ find . -not -regex ".*test.*"                   .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

обычно родной способ мы делаем вещи в linux и то, как мы думаем, слева направо.
Так что вы бы пойти и написать то, что вы ищете в первую очередь:

find / -name "*.php"

тогда вы, вероятно, нажмете enter и поймете, что получаете слишком много файлов из каталоги, которые вы не хотите. Давайте исключим /media, чтобы избежать поиска подключенных дисков.
Теперь вы должны просто добавить следующее к предыдущей команде:

-print -o -path '/media' -prune

Итак, последняя команда это:

find / -name "*.php" -print -o -path '/media' -prune

...............|--- ...................||

Я думаю, что эта структура намного проще и коррелирует с правильным подходом

добавление к советам, приведенным в других ответах (у меня нет репутации для создания ответов)...

при объединении -prune С другими выражениями существует тонкая разница в поведении в зависимости от того, какие другие выражения используются.

@Laurence Gonsalves' пример найдет "*.ФОО" файлы, которые не находятся под ".снимок" каталоги:-

find . -name .snapshot -prune -o -name '*.foo' -print

однако эта немного другая короткая рука будет, возможно, непреднамеренно, также перечислять

Prune-это не рекурсия в любом коммутаторе каталогов.

из man-страницы

Если-глубина не задана, true; если файл является каталогом, не спускайтесь в него. Если-глубина задана, ложь; никакого эффекта.

в основном он не будет десенд в любые подкаталоги.

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

у вас есть следующие каталоги

  • / home / test2
  • в/Home/test2 на/условие_2

Если вы запустите find -name test2:

он вернет оба каталога

Если вы запустите find -name test2 -prune:

он вернется только /home / test2, поскольку он не будет спускаться в /home /test2, чтобы найти/home/test2 / test2

Я не эксперт в этом (и эта страница была очень полезна вместе с http://mywiki.wooledge.org/UsingFind)

только что заметил -path на пути полностью соответствует строке / пути, который приходит сразу после find (. в этих примерах) где как -name соответствует всем имена.

find . -path ./.git  -prune -o -name file  -print

блокирует .каталог git в вашем текущем каталоге ( как ваша находка в . )

find . -name .git  -prune -o -name file  -print

блокирует все .ГИТ поддиректории рекурсивно.

Примечание ./ очень важно!! -path должен соответствовать пути, привязанному к .или все, что приходит сразу после найти если вы получаете спички с ним (с другой стороны или'-o') там, вероятно, не обрезается! Я наивно не знал об этом, и это поставило меня в using-path, когда это здорово, когда вы не хотите обрезать все подкаталоги с помощью то же самое базовое имя :D

показать все, включая сам dir, но не его длинное скучное содержание:

find . -print -name dir -prune

Если Вы читаете все хорошие ответы здесь, я понимаю, что следующие все возвращают те же результаты:

find . -path ./dir1\*  -prune -o -print

find . -path ./dir1  -prune -o -print

find . -path ./dir1\*  -o -print
#look no prune at all!

но последний займет намного больше времени, поскольку он все еще ищет все в dir1. Я думаю, реальный вопрос заключается в том, как -or из нежелательных результатов без фактического поиска их.

поэтому я думаю, что чернослив означает, что не приличные прошлые матчи, но отметьте его как сделанный...

http://www.gnu.org/software/findutils/manual/html_mono/find.html "Это, однако, не связано с эффектом действия "- prune " (который только предотвращает дальнейшее снижение, он не гарантирует, что мы игнорируем этот элемент). Вместо этого этот эффект обусловлен использованием ‘-o’. Так как левая сторона условия " или "преуспела./src / emacs, нет необходимости оценивать правую сторону (’- print') вообще для этого конкретного файла."

Comments

    Ничего не найдено.