目录
8、与grep, xargs等结合,在结果中筛选或执行命令:
????????Linux的find命令是最重要和最常用的命令之一,用于在目录树中查找文件和目录。它可以根据各种条件进行搜索,包括文件名、权限、用户和组、文件类型、文件大小、日期和时间等。
????????同时也有一些组合应用,可以方便进行各种操作。
????????很多文档都根据命令的语法来介绍,要想完成一个具体的搜索任务,还需要看每个命令,找到对应的用法。
????????为了节省大家的时间,本文简单介绍下find的语法,以方便查询;同时按照一些实际需要完成的任务,来介绍find的一些用途。也就是根据具体的应用场景来使用find命令。
????????????????find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
????????表达式列表中的“选项”。这些选项控制find的行为,但在最后一个路径名之后立即指定。五个“real”选项-H、-L、-P、-D和-O必须出现在第一个路径名之前(如果有的话)。双破折号--也可以用来表示任何剩余的参数都不是选项(尽管如果在起始点列表中使用通配符,则确保所有起始点都以“./”或“/”开头通常更安全)。
????????-H、-L和-P选项控制符号链接的处理。后面的命令行参数将被视为文件名或要检查的目录,直到第一个以“-”开头的参数,或参数“(”或“!”。该参数和后面的任何参数自变量被认为是描述要搜索的内容的表达式。如果没有给出路径,则使用当前目录。如果没有给出任何表达式,而是使用表达式-print(但无论如何,您可能应该考虑使用-print0)
????????打印诊断信息;这有助于诊断find为什么没有按您的意愿进行操作的问题。调试列表选项应以逗号分隔。在findutils的各个版本之间,调试选项的兼容性并不能得到保证。对于完整的有效调试选项列表,请参阅find-D帮助的输出。有效的调试选项包括帮助解释调试选项
????????tree????????以原始和优化的形式显示表达式树。
????????stat????????使用stat和lstat系统调用检查文件时打印消息。find程序尽量减少此类调用。
????????opt????????打印与表达式树的优化有关的诊断信息;请参阅-O选项。
????????rates????????打印一个摘要,指示每个谓词成功或失败的频率。
????????-Olevel 启用查询优化。find程序对测试进行重新排序,以加快执行速度,同时保持整体效果;也就是说,具有副作用的谓词不会相对于彼此重新排序。优化级别有0,1,2,3几个等级。
????????表达式expression由1选项options(影响整体操作而不是特定文件的处理,并且总是返回true)、2测试tests(返回true或false值)和3动作actions(具有单向作用,并返回true或false值)组成,所有这些都由运算符分隔。
????????所有选项始终返回true。除了-daystart、-follow和-regextype之外,这些选项会影响所有测试,包括在该选项之前指定的测试。这是因为在解析命令行时会处理选项,而在检查文件之前,测试不会执行任何操作。-daystart、-follow和-regextype选项在这方面有所不同,仅对稍后出现在命令行中的测试有影响。因此,为了清晰起见,最好将它们放在表达式的开头。如果你不这样做,就会发出警告。常用的有如下:
????????-daystart
????????-depth
????????-follow
????????-help?????
????????-maxdepth???
????????-mindepth
????????-mount
????????-noleaf
????????-version
????????一些测试,例如-newerXY和-samefile,允许在当前检查的文件和命令行上指定的某个参考文件之间进行比较。当使用这些测试时,参考文件的解释由选项-H、-L和-P以及之前的任何后续选项决定,但在解析命令行时,只检查一次参考文件。如果无法检查引用文件(例如,stat(2)系统调用失败),则会发出错误消息, find以非零状态退出。有如下常用的tests:
?????? 常见的有如下:
????????????????-delete
????????????????-exec command
????????????????-exec command {} +
????????????????-execdir
????????????????-printf format
????????????????-prune True;
(1)查找当前目录及其子目录下名为 "example.txt" 的文件:
???????????? find . -name "example.txt"`
(2)查找根目录/及其子目录下名为 "example.txt" 的文件:
???????????? find / -name "example.txt"`
(3)当前目录及其子目录下所有文件后缀为?.c?的文件列出来:
???????????? find . -name "*.c"`
(1)查找当前目录及其子目录下的所有普通文件:
????? ??? find . -type f
(2)查找当前目录及其子目录下的所有目录:
????? ??? find . -type d
????????查找大于 10MB 的文件:
???? ???????????? find . -size +10M
? ? ? ? (1)查找在过去 7 天内修改过的文件:
????????????????find . -mtime -7
? ? ? ?(2)查找 /var/log/test 目录下在 7 天前修改过的文件:
????????????????find /var/log/test -mtime +7
????????查找所有可执行文件:
??? ?????? find . -executable
????????查找所有属于用户 "john" 的文件:
???? ???? find . -user john
(1)查找所有 .txt 扩展名且在过去 7 天内修改过的文件:
???? ???? find . -type f -name "*.txt" -mtime -7
(2)查找 /usr/local/log 目录中更改时间在 7 日以前的普通文件,并在删除之前询问它们:
????????find /usr/local/log -type f -mtime +7 -ok rm {} \;
? ? ? ? (1)grep可以用来将 find 的输出作为参数,再进行一次筛选,例如,查询所有 .cpp扩展名的文件,同时文件名或者路径中带有“视频监控平台”的文件,可以这样做:
????????????????find . -name "*.cpp" | grep 视频监控平台
????????执行结果如下:
? ? ? ? (2)xargs 可以用来将 find 的输出作为参数传递给其他命令。例如,如果你想删除所有 .bak 扩展名的文件,你可以这样做:????
????????????????????????find . -name "*.bak" | xargs rm -f
? ? ? ? (1)可以使用 -exec 选项来对找到的每个文件执行一个命令。例如,为找到的所有 .sh文件打印其修改时间:????
????????????????find . -name "*.sh" -exec ls -l {} \;
?????? 执行结果如下:
? ? ? ? (2)查找当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件,并列出完整路径:
????????????????find . -type f -perm 644 -exec ls -l {} \;
? ? ? ? (3)查找系统中所有文件长度为 0 的普通文件,并列出它们的完整路径:
????????????????find / -type f -size 0 -exec ls -l {} \;??????
? ? ? ? (4)找到tes文件并执行操作(例如删除):
????????????????find /path/search -name "tes" -exec rm {} \;
? ? ? ? (1)使用 -prune 选项来避免进入某些目录。例如,避免进入 .git 子目录:????
????????????????find . -path .git -prune -o -print
? ? ? ? (2)查找所有 .txt 文件,但忽略大小为 0 的文件:
???? ???????????? find . -name "*.txt" ! -size 0 -print
????????默认情况下,find 命令会递归地查找子目录。如果你想限制搜索深度,可以使用 -maxdepth 和 -mindepth 选项。例如,只在当前目录中查找(不包括子目录):
?? ??????????????? find . -maxdepth 1 -name "*.txt" -print