Как использовать '-чернослив' опция 'находки' в sh?

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


Более подробный вопрос похож на это:

Запишите сценарий оболочки, changeall, который имеет интерфейс как changeall [-r|-R] "string1" "string2". Это найдет все файлы с суффиксом .h, .C, .cc, или .cpp и измените все случаи string1 кому: string2. -r опция для пребывания в текущем dir только или включая subdir's.

Примечание:

  1. Для нерекурсивного случая, ls НЕ позволяется, мы могли только использовать find и sed.
  2. Я попробовал find -depth но это НЕ поддерживалось. Вот почему я задавался вопросом если -prune мог помочь, но не понял примера от man find.

EDIT2: Я делал уроки, я не задавал вопрос в больших деталях, потому что я хотел бы закончить его сам. Так как я уже сделанный это и рука в нем, теперь я могу заявить целый вопрос. Кроме того, мне удалось выполнить задание без использования -prune, но хотел бы изучить это так или иначе.

206
задан Lii 12 August 2019 в 05:17
поделиться

4 ответа

The thing I'd found confusing about about -prune is that it's an action (like -print), not a test (like -name). It alters the "to-do" list, but always returns true.

The general pattern for using -prune is this:

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

You pretty much always want the -o (logical OR) immediately after -prune, because that first part of the test (up to and including -prune) will return false for the stuff you actually want (ie: the stuff you don't want to prune out).

Here's an example:

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

This will find the "*.foo" files that aren't under ".snapshot" directories. In this example, -name .snapshot makes up the [conditions to prune], and -name '*.foo' -print is [your usual conditions] and [actions to perform].

Important notes:

  1. If all you want to do is print the results you might be used to leaving out the -print action. You generally don't want to do that when using -prune.

    The default behavior of find is to "and" the entire expression with the -print action if there are no actions other than -prune (ironically) at the end. That means that writing this:

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

    is equivalent to writing this:

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

    which means that it'll also print out the name of the directory you're pruning, which usually isn't what you want. Instead it's better to explicitly specify the -print action if that's what you want:

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

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

     найти. -name '.git *' -prune -o -type f -print # ЭТО НЕ ДЕЛАЙТЕ
    

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

     find. -name '.git *' -type d -prune -o -type f -print # СДЕЛАЙТЕ ЭТО
    

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

417
ответ дан 23 November 2019 в 04:46
поделиться

Существует довольно много ответов; некоторые из них немного слишком много тяжелы теорией. Я уеду , почему я должен был сократить однажды поэтому, возможно, , вид need-first/example объяснения полезен для кого-то :)

проблема

, у меня была папка приблизительно с 20 каталогами узла, каждый имеющий node_modules каталог как ожидалось.

, После того как Вы входите в любой проект, Вы видите каждого ../node_modules/module. Но Вы знаете, как это. Почти каждый модуль имеет зависимости, поэтому на что Вы смотрите, больше похож projectN/node_modules/moduleX/node_modules/moduleZ...

, я не хотел тонуть со списком с зависимостью зависимости...

Знание -d n / -depth n, это не помогло бы мне, как основной/первый node_modules каталог, который я хотел каждого проекта, был на различной глубине, как это:

Projects/MysuperProjectName/project/node_modules/...
Projects/Whatshisname/version3/project/node_modules/...
Projects/project/node_modules/...
Projects/MysuperProjectName/testProject/november2015Copy/project/node_modules/...
[...]

, Как я могу получить первое список путей, заканчивающихся в первом node_modules, и переместиться в следующий проект получить то же?

Входят -prune

, Когда Вы добавите -prune, у Вас все еще будет стандартный рекурсивный поиск. Каждый "путь" проанализирован, и каждая находка выводит слюну, и find подавляет рытье как хороший парень. Но это - рытье вниз для больше node_modules, что я не хотел.

Так, различие - то, что в любом из тех различных путей, -prune будет find, чтобы прекратить рыть далее вниз, что конкретная авеню, когда она нашла Ваш объект. В моем случае, node_modules папка.

0
ответ дан 23 November 2019 в 04:46
поделиться

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

$ 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
26
ответ дан 23 November 2019 в 04:46
поделиться

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

Из справочной страницы

Если -depth не задана, то true; если файл является каталогом, не спускайтесь в него. If -depth is given, false; no effect.

Basically it will not desend into any sub directories.

Take this example:

You have the following directories

  • /home/test2
  • /home/test2/test2

If you run find -name test2:

It will return both directories

If you run find -name test2 -prune:

It will return only /home/test2 as it will not descend into /home/test2 to find /home/test2/test2

3
ответ дан 23 November 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: