find 命令的工作方式
find命令的工作方式如下:沿着文件层次结构向下遍历,匹配符合条件的文件,并执行相应的操作。
find命令异常强大,因为它允许您按文件名、文件类型、用户甚至是时间戳查找文件。使用 find 命令,您不但可以找到具这些属性任意组合的文件,还可以对它找到的文件执行操作。
[注意:本文使用的 find 版本是 GNU 版本,因此,某些细节可能与其他版本的 find 有所不同。]
基本格式开始之前,我们先来看一下 find 命令的基本结构:
find start_directory test options criteria_to_match action_to_perform_on_results start_directory: find 命令所查找的路径,可指定多个路径。
1 2
# find . -print # find / /etc /usr "*.c"
以上命令, find 将在当前目录("."表示)中查找任何文件。
-print 指明打印出匹配文件的文件名(路径)。当使用 -print时, ‘\n’作为用于分隔文件的定界符。
-print0 指明使用 '\0' 作为定界符来打印每一个匹配的文件名。当文件名中包含空白符或换行符时,就非常有用了。
如果用户没有相应权限,在使用find的时候,会生成很多错误信息: Permission denied
我们可以把错误信息重定向,以保证结果清晰明了:
1
# find /etc -name "*.sh" 2>/dev/null
根据文件名或正则表达式匹配搜索
选项 -name 参数指定了文件名所必须匹配的字符串。我们可以将通配符作为参数使用。注意,
find 还有一个选项 -iname (忽略大小写),该选项的作用和 -name类似,只不过在匹配文件名的时候忽略大小写。
注意: 你需要对通配符进行转义以确保它传递到 find 命令并且不被 shell 解释。
1 2 3 4 5
# find . -name "*.sh" ./sct2.sh ./first.sh ./FIRST.sh ./one.sh
如果想匹配多个条件中的一个,可以采用 OR 条件操作:
1 2 3 4 5 6
# find . \( -name "*.sh" -o -name "*.txt" \) -print ./sct2.sh ./a.txt ./first.sh ./FIRST.sh ./one.sh
选项 -path 参数可以使用通配符来匹配文件路径或文件。-name总是用给定的文件名进行匹配。-path则将文件路径作为一个整体进行匹配。
选项 -regex 的参数和-path类似,只不过 -regex是基于正则表达式来匹配文件路径的,This is a match on the whole path, not a search。类似的,-iregex 用于正则表达式匹配时忽略大小写。
基于目录深度的搜索: maxdepth, mindepth, 忽略某个目录find 命令在使用时会遍历所有的子目录。我们可以采用一些深度参数来限制 find 命令遍历的深度。 -maxdepth 和 -mindepth 就是这类参数。
大多数情况下,我们只需在当前目录中进行搜索,无须再继续向下查找。对于这种情况,我们使用深度参数来限制find 命令向下查找的深度。如果只允许 find 在当前目录中查找,深度可以设置为1; 当需要向下两级时,深度可以设置为2; 其他情况可以一次类推。
我们可以通过 -maxdepth 参数指定最大深度。与此类似,我们也可以指定一个最小的深度,使用 -mindepth参数设置最小深度。
-maxdepth和-mindepth应该作为第一个选项出现。如果作为之后的选项,就可能会影响find的效率,因为它不得不进行一些不必要的检查。
find 命令在使用时会遍历所有的子目录。使用find进行查找的时候,有时候需要忽略某些目录,可以使用 -prune 参数来进行过滤,但必须要注意忽略的路径参数必须紧跟着搜索的路径之后,否则该参数无法起作用。
以下是指定搜索/home/carryf目录下的所有文件,但是会忽略/home/carryf/astetc的路径:
find /home/carryf -path "/home/carryf/astetc" -prune -o -type f -print
如果按照文件名来搜索则为:
find /home/carryf -path "/home/carryf/astetc" -prune -o -type f -name "cdr_*.conf" -print
如果要忽略两个以上的路径如何处理?
find /home/carryf \( -path "/home/carryf/astetc" -o -path "/home/carryf/etc" \) -prune -o -type f -print
find /home/carryf \( -path "/home/carryf/astetc" -o -path "/home/carryf/etc" \) -prune -o -type f -name "*.conf" -print
注意\( 和\) 前后都有空格。
基于文件类型搜索