解释find的-path和-prune选项


11

我有一个最容易理解的简单脚本,不清楚的是find命令。我有很多文档,但并不能使其更加清晰。我的想法是,它的工作方式类似于for循环,当前找到的文件被替换为{},并复制到$ 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

这只是我知道我应该能够弄清楚的文档。

路径模式

文件名与外壳模式匹配。元字符不对待/ 特别; 因此,例如,find。-path“ ./sr*sc”将打印一个名为./src/misc的目录的条目(如果存在)。要忽略整个目录树,请使用-prune而不是检查树中的每个文件。例如,要跳过目录src / emacs及其下的所有文件和目录,并打印找到的其他文件的名称,请执行以下操作:

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

Findutils手册

-动作:-exec命令;-execdir操作的此不安全变体由POSIX指定。主要区别在于命令是在调用find的目录中执行的,这意味着{}会扩展到相对路径,起始路径为起始目录之一的名称,而不只是匹配文件的基本名称。

尽管一些实现的查找替换{}只有在它自身出现的说法,GNU 发现内容替换{} 凡出现。

例如,要将当前目录中或以下的每个C头文件与文件/ tmp / master进行比较:

      find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'


我认为,即使在find:prune的答案没有忽略指定路径的答案的情况下,它也是重复的find-path的解释,该答案似乎适用于此问题。也许find-path解释的答案对具有脚本编写经验的人来说是有意义的,但是它们对我没有帮助。到目前为止,即使我才开始研究它们,这里给出的答案对我来说还是更有意义。
flerb

Answers:


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显然带的部分是必要的,以避免对备份进行备份...


如果我能理解,则:find将遍历$ HOME中它有权访问的每个目录,但$ HOME / $ dir_name除外,因为它将不会进入(因为修剪操作将评估为true,而or将(不接受),搜索以$ file_suffix结尾的文件。然后,一旦找到一个,它将执行cp“ found_file.sh”到$ HOME / $ dir_name中?另外,-path允许使用文件路径,当您希望查找到目录而不仅仅是在当前目录中工作时,它很有用?
flerb

您的理解几乎是正确的。-path就像-name:选择文件一样。区别在于,-name将模式与文件名-path匹配,而将模式与完整路径名匹配。find总是下降到子目录,除非通过防止-maxdepth-prune等等
AlexP

哦! -path应用于$ HOME / $ dir_name -prune,然后,这就是命令的顺序,这使我很困惑,而-prune命令需要-path,因为它需要匹配修剪目录的完整路径。
flerb

@Darren我不确定这是否很准确。-path $HOME/$dir_name是一个动作。该测试检查正在检查的当前文件的路径是否匹配$HOME/$dir_name-prune是一个单独的动作。我认为您第一条评论的一句话准确地反映了它的工作原理。
David Z

将其视为管道会丢失什么吗?我将-prune与-print交换,并认为流程现在已经很清楚:find $ HOME | -path $ 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,请参阅/programming/1489277/how-to-use-prune-option-of-find-in-sh

-o表示OR,所以-path <some_path>OR-name *$file_suffix

-exec 表示执行命令。

cp {} $HOME/$dir_name/ 将所有匹配的文件复制到 $HOME/$dir_name/

\;表示终止-exec命令

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.