Объясните параметры поиска -path и -prune

11

У меня есть простой скрипт, который я понимаю больше всего, это команда find, которая неясна. У меня много документации, но она не очень понятна. Моя мысль в том , что он работает как для цикла, то в настоящее время находится файл обменен в течение {} и скопировать в $ HOME / $ DIR_NAME, но как поиск с -path и -prune -o работой? Досадно иметь такую ​​конкретную и актуальную документацию и все еще не знать, что происходит.

#!/bin/bash
# The files will be search on from the user's home
# directory and can only be backed up to a directory
# within $HOME

read -p "Which file types do you want to backup " file_suffix
read -p "Which directory do you want to backup to " dir_name

# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name

# The find command will copy files that match the
# search criteria ie .sh . The -path, -prune and -o
# options are to exclude the backdirectory from the
# backup.
find $HOME -path $HOME/$dir_name -prune -o \
-name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
exit 0

Это просто документация, из которой я знаю, что смогу понять это.

шаблон пути

Имя файла соответствует шаблону оболочки. Метасимволы не обрабатывают / или . специально; так, например, найди. -path "./sr*sc" напечатает запись для каталога с именем ./src/misc (если он существует). Чтобы игнорировать все дерево каталогов, используйте -prune вместо проверки каждого файла в дереве. Например, чтобы пропустить каталог src / emacs и все файлы и каталоги в нем, и напечатать имена других найденных файлов, сделайте что-то вроде этого:

find . -path ./src/emacs -prune -o -print

Из руководства Findutils

- Действие: команда -exec; Этот небезопасный вариант действия -execdir указан в POSIX. Основное отличие состоит в том, что команда выполняется в каталоге, из которого была вызвана команда find , это означает, что {} раскрывается в относительный путь, начинающийся с имени одного из начальных каталогов, а не только с базового имени соответствующего файла.

В то время как некоторые реализации find заменяют {} только там, где оно появляется само по себе в аргументе, GNU find заменяет {} везде, где оно появляется.

А также

Например, чтобы сравнить каждый заголовочный файл C в или ниже текущего каталога с файлом / tmp / master:

      find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'
flerb
источник
Я думаю, что если что-то будет дубликатом объясненного пути поиска, даже если ответ при поиске: prune не игнорирует указанный путь, есть ответ, который, кажется, применим к этому вопросу. Может быть, ответы с объяснением пути поиска имеют смысл для кого-то более опытного в написании сценариев, но они не помогают мне. Приведенные здесь ответы имеют для меня больше смысла, хотя я только начинаю их изучать.
Флерб

Ответы:

23

-pathработает точно так же -name, но применяет шаблон ко всему пути к файлу, который проверяется, а не к последнему компоненту.

-prune запрещает спускаться ниже найденного файла, если это был каталог.

Собрав все вместе, команда

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
  1. Начинает искать файлы в $HOME.
  2. Если он находит файл, соответствующий $HOME/$dir_nameему, он не будет идти ниже («подрезает» подкаталог).
  3. В противном случае ( -o), если он найдет соответствующий файл, скопирует *$file_suffixего в $HOME/$dir_name/.

Похоже, идея сделать резервную копию некоторого содержимого $HOMEв подкаталоге $HOME. Части с -pruneявно необходимы, чтобы избежать создания резервных копий ...

AlexP
источник
Если я понимаю, то: find будет перебирать каждый каталог в $ HOME, на который у него есть разрешения, за исключением $ HOME / $ dir_name, в которое он не будет опускаться (потому что действие обрезки будет иметь значение true, а значение or будет не принимается), поиск файлов, которые заканчиваются на $ file_suffix. Затем, как только он его найдет, он выполнит cp "found_file.sh" в $ HOME / $ dir_name? Кроме того, -path позволяет указать путь к файлу и полезен, если вы хотите, чтобы find находился в каталогах, а не просто работал в текущем каталоге?
Флерб
Ваше понимание почти правильно. -pathработает так же, как -name: он выбирает файлы. Разница в том, что -nameшаблон соответствует имени файла, а -pathшаблон соответствует полному пути. findвсегда спускается в подкаталоги, если это не предотвращено -maxdepthи -pruneт. д.
AlexP
Ой! -path применяется к $ HOME / $ dir_name -prune, это порядок команд, который меня напутал, и -path необходим для команды prune, потому что он должен соответствовать полному пути сокращенного каталога.
Флерб
@Darren Я не уверен, что это довольно точно. -path $HOME/$dir_nameэто одно действие. Это тест, который проверяет, совпадает ли путь текущего проверяемого файла с тем, что $HOME/$dir_nameесть. -pruneэто отдельное действие. Я думаю, что первое предложение вашего первого комментария точно отражает, как это работает.
Дэвид З,
Будет ли что-то упущено, чтобы увидеть это как трубу? Я поменял -prune с -print и теперь думаю, что процесс понятен: find $ HOME | путь $ HOME / $ dir_name | -print
flerb
4

Это часть команды find, оператор -exec.

Это позволяет вам взаимодействовать с файлом / каталогом, найденным findкомандой.

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;

find $HOME означает найти файлы / каталоги в $ HOME

Чтобы понять -path <some_path>, смотрите объяснение `find -path`

Чтобы понять -prune, см. Https://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh

-oозначает ИЛИ, так -path <some_path>ИЛИ-name *$file_suffix

-exec значит выполнить команду.

cp {} $HOME/$dir_name/ скопировать любые файлы, соответствующие $HOME/$dir_name/

\;значит прекратить -execкоманду

thecarpy
источник