find命令

find 命令用于在指定目录下查找文件和目录。它可以使用不同的选项来过滤和限制查找的结果。

语法:find [paths] [expression] [actions]

参数说明:

  • path:要查找的目录路径,可以是一个目录或文件名,也可以是多个路径,多个路径之间用空格分隔,如果未指定路径,则默认为当前目录。

  • expression:可选参数,用于指定查找的条件,可以是文件名、文件类型、文件大小等等。

  • 动作:可选的,用于对匹配到的文件执行操作,比如删除、复制等。

find常用参数

  • -name pattern :搜索时使用 pattern 对文件名进行匹配
  • -type t :根据文件类型搜索,可以是 f(普通文件)、d(目录)、l(符号链接)、p(管道文件)、b(块设备文件)、c(字符设备文件)
  • -path pattern :搜索时使用 pattern 对文件路径进行匹配
  • -size [+-]n[ckMGTP] :根据文件大小搜索:支持使用 + 或 - 表示大于或小于指定大小,单位可以是 c(字节)、w(字数)、b(块数)、k(KB)、M(MB)或 G(GB)
  • -user uname :按文件所有者查找,支持使用通配符 * 和 ?
  • -group gname :按文件所属组查找
  • -uid userID :按照用户 ID 査找所有者是指定 ID 的文件
  • -gid groupID :按照用户组 ID 査找所属组是指定 ID 的文件
  • -perm mode :根据文件权限搜索
  • -delete :删除检索到的文件
  • -ls :打印搜索到的文件的详细信息
  • -empty :检索空文件或空目录
  • -exec :对搜索到的结果执行特定的命令,命令形式为:"command {} \;" 因为分号是 Shell 中有特殊含义的符号,所以需要转义(\)或需要使用单引号括起来
  • -ok :和 -exec 作用相同,但以一种更加安全的方式来执行命令,在执行每条命令之前都会给出提示,让用户来确定是否要执行
  • -amin [+-]n:查找在 n 分钟内被访问过的文件,支持使用 + 或 - 表示在指定时间前或后
  • -cmin [+-]n :查找在 n 分钟内状态发生变化的文件(例如权限),支持使用 + 或 - 表示在指定时间前或后
  • -mmin [+-]n :查找在 n 分钟内被修改过的文件,支持使用 + 或 - 表示在指定时间前或后
  • -atime [+-]n :查找在 n*24 小时内被访问过的文件,支持使用 + 或 - 表示在指定时间前或后
  • -ctime [+-]n :查找在 n*24 小时内状态发生变化的文件(例如权限),支持使用 + 或 - 表示在指定时间前或后
  • -mtime [+-]n :查找在 n*24 小时内被修改过的文件,支持使用 + 或 - 表示在指定时间前或后
  • -newer file1 ! file2:查找更改时间比文件file1 新但比文件file2旧的文件。
  • -iname pattern :同 -name,忽略大小写
  • -ipath pattern :同 -path,忽略大小写
  • -depth n :检索深度为 n 的文件,即位于指定目录以下 n 层的文件
  • -maxdepth n :指定递归的最大层数为 n,默认不限制深度
  • -mindepth n :指定递归的最小层数为 n,默认不限制深度
  • -nouser:查找没有有效所有者的文件
  • -nogroup:查找没有有效所属组的文件
  • -fstype type :指定文件所在的文件系统的类型
  • -not:取反操作,排除满足条件的文件或目录
  • -and:与操作,同时满足多个条件
  • -or:或操作,满足任意一个条件即可
  • -fprint filename:将匹配的文件输出到文件。
  • -print: 将匹配到的文件输出到标准输出
  • -print0: 将匹配到的文件输出到标准输出,且输出的文件列表以 null(\0) 分隔
  • -follow:如果find命里遇到符号链接文件,就跟踪至连接所指向的文件。

根据时间日期进行检索

Linux 系统中,与文件相关联的时间参数有以下三种:

  • 修改时间(Modification time):最后一次文件内容有过更改的时间点
  • 访问时间(Access time):最后一次文件有被读取过的时间点
  • 变更时间(Change time):最后一次文件有被变更过的时间点(如内容被修改,或权限等 metadata 被修改)

与此对应的是 find 命令中的:

  • -amin, -cmin, -mmin:单位是分钟
  • -atime, -ctime, -mtime:单位是天

“-amin n"和”-atime n"的处理方法都是:根据当前时间和文件的相应时间属性求差值,然后比较差值和参数n,看是否符合要求。但是这个求差值的过程却有很大不同,他们的不同也代表了两组(基于分钟和基于天)的不同:

"-amin n"
(1)求Δt,用当前时间减去文件时间值即得到Δt,Δt = tnow - tfile;
(2)求浮点数f,用Δt除以1分钟,f = Δt / 1min;
(3)将f的小数部分入到整数部分,得到差。即,不管f是6.0102还是6.8901,差值都等于7
 
"-atime n"
(1)求Δt,用当前时间减去文件时间值即得到Δt,Δt = tnow - tfile;
(2)求浮点数f,用Δt处以24小时,f = Δt / 24hours;
(3)将f的小数部分都舍掉,得到差。即,不管f是6.0102还是6.8901,差都等于6
 
-amin +3     +3表示差值大于3
-amin -3     -3表示差值小于3
-amin 3     表示差值等于3

正数应该表示时间之前,负数表示时间之内。

例如:-mtime 0 表示查找今天修改过的文件,-mtime -7 表示查找一周以前修改过的文件。

关于时间 n 参数的说明:

  • +n:查找比 n 天前更早的文件或目录。
  • -n:查找在 n 天内更改过属性的文件或目录。
  • n:查找在 n 天前(指定那一天)更改过属性的文件或目录。
find /usr -type f -mtime +50 -mtime -100 
检索 /usr 下 50 到 100 天之前修改过的文件

find /usr -type f -mtime 2 -amin 5 
检索 /usr 下两天前被修改过且 5 分钟前又读取过的文件

find . -type f -atime -7
搜索最近七天内被访问过的所有文件
 
find . -type f -atime 7
搜索恰好在七天前被访问过的所有文件
 
find . -type f -atime +7
搜索超过七天被访问过的所有文件
 
find . -type f -amin +10
搜索访问时间超过10分钟的所有文件
 
-anewer file
-cnewer file
-newer file
 
find . -type f -newer file.log
找出比file.log内容修改时间更晚的所有文件

根据文件权限检索

使用 -perm 选项以文件权限为依据进行搜索。

使用符号形式

如需要检索 /usr 目录下权限为 rwxr-xr-x 的文件,可以使用以下命令:

find /usr -perm u=rwx,g=rx,o=rx

搜索 /usr 目录下所有权限为 r-xr-xr-x(即系统中的所有用户都只有读写权限)的文件和目录,可以使用以下命令:

find /usr -perm a=rx

很多时候,我们只想匹配文件权限的一个子集。比如,检索可以直接被任何用户执行的文件,即只关心文件的执行权限,而不用管其读写权限是什么。

上述的需求可以通过以下命令实现:

find / -type f -perm /a=x

其中 a=x 前面的 / 符号即用来表示只匹配权限的某个子集(执行权限),而不用关心其他权限的具体设置。

使用数字形式

-perm 选项也支持数字形式的文件权限标记。

  • -perm 权限模式:査找文件权限刚好等于"权限模式"的文件
  • -perm -权限模式:査找文件权限全部包含"权限模式"的文件
  • -perm +权限模式(/权限模式):査找文件权限包含"权限模式"的任意一个权限的文件
搜索 /usr 目录下权限为 644(即 rwxr-xr-x)的文件
find /usr -perm 644 

査找文件权限全部包含w的文件
find . -perm -222

査找文件权限包含w的任意一个权限的文件
find . -perm /222

反义匹配

find 命令也允许用户对当前的匹配条件进行“反义”(类似于逻辑非操作),也可以使用 -not 选项

如需要检索 /usr 下所有文件名不以 .txt 为后缀的文件。可以使用以下命令:

find /usr -type f ! -name '*.txt'

也可以“翻转”任何其他的筛选条件,如:

find /usr -type f ! -empty //检索 /usr 下所有内容不为空的文件

逻辑组合

除取反操作外,find 命令还支持 “and” 和 “or” 两种逻辑运算,对应的命令选项分别是 -a-o。通过这两个选项可以对搜索条件进行更复杂的组合。

此外还可以使用小括号对搜索条件进行分组。注意 find 命令中的小括号常需要用单引号包裹起来。因小括号在 Shell 中有特殊的含义。

如检索 /usr 下文件名以 python 开头且类型为目录的文件:

find /usr -type d -name 'python*'
#该命令等同于:
find /usr -type d -a -name 'python*'

更复杂的组合形式如:

find / '(' -mmin -5 -o -mtime +50 ')' -a -type f
find . -size +2k -a -type f
在当前目录下搜索大于2KB,并且文件类型是普通文件的文件

find . -mtime -3 -a -perm 644
在当前目录下搜索3天以内修改过,并且权限是644的文件

find / -name 'temp' -o -name 'install*'
在根目录下查找文件名为’temp’或是匹配’install*’的所有文件
 
find ! -name 'Test*'
在当前目录下查找不以Test开头的文件
 
find . -name "*.txt" -o -print
如果表达式-name "*.txt"为真,就不再执行另一个表达式-print,即查找所有不是以.txt结尾的文件。
 
find . -name "*e*[0-9]*" ! -type d -print
查找当前目录下,文件名中包括字母'e',在'e'之后又有数字的不是目录文件的所有文件
 
find . -name "[A-Za-b]*"
当前目录及子目录中查找文件名以一个大写字母开头或者以小写a或b开头的文件
 
-iname
-name区分大小写,如果不想区分大小写可以使用-iname测试项。
'i'可以加在许多选项前面,比如-ipath,-iregex,-iwholename等等,都是不区分大小写。

执行自定义命令

-exec 选项可以对搜索到的结果执行特定的命令。

如需要将 home 目录下所有的 MP3 音频文件复制到移动存储设备(假设路径是 /media/MyDrive),可使用下面的命令:

find ~ -type f -name '*.mp3' -exec cp {} /media/MyDrive ';'

其中的大括号({})作为检索到的文件的 占位符 ,而分号( ;)作为命令结束的标志。因为分号是 Shell 中有特殊含义的符号,所以需要使用单引号括起来或使用转义符号(\)转义。

每当 find 命令检索到一个符合条件的文件,会使用其完整路径取代命令中的 {},然后执行 -exec 后面的命令一次。

另一个很重要的用法是,在多个文件中检索某个指定的字符串。

如在用户主目录下的所有文件中检索字符串 hello ,可以使用如下命令:

find ~ -type f -exec grep -l hello {} \;

更多例子:

find . EXPR1 -exec command {} \;
注意:后一个花括号'}'和'\'之间有一个空格,最后以分号;结尾,因为各个系统中分号会有不同的意义,所以前面加反斜杠。  
{} 花括号代表前面find查找出来的文件名。
 
find . -type f -exec ls -l {} \;
查找当前目录下的所有普通文件,并用ls命令输出
 
find .-type f -user root -exec chown tom {} \;
找出当前目录下所有root的文件,并把所有者更改为用户tom
 
find . -type f -name "*.txt" -exec cat {} \;> all.txt
查找当前目录下所有.txt文件并把他们拼接起来写入到all.txt文件中
 
find . -type f -mtime +30 -name "*.log" -exec cp {} old \;
将30天前的.log文件移动到old目录中
 
find . -type f -name "*.txt" -exec printf "File: %s\n" {} \;
找出当前目录下所有.txt文件并以“File:文件名”的形式打印出来
 
因为单行命令中-exec参数中无法使用多个命令,使用脚本可以实现在-exec之后接受多条命令
-exec ./text.sh {} \;

-exec 选项中的 + 符号

创建 Gzip 格式的压缩文件的命令为:

tar -czvf filename.tar.gz <list of files>

现在假设需要将用户主目录下所有的 MP3 文件添加到压缩包 music.tar.gz 中,直观的感觉是,其命令应为如下形式:

find ~ -type f -name '*.mp3' -exec tar -czvf music.tar.gz {} ';'

实际情况是,这样得到的 music.tar.gz 其实只包含一个 MP3 文件。

原因是 find 命令每次发现一个音频文件,都会再执行一次 -exec 选项后面的压缩命令。导致先前生成的压缩包被覆盖。

可以先让 find 命令检索出所有符合条件的音频文件,再将得到的文件列表传递给后面的压缩命令。完整的命令如下:

find ~ -type f -name '*.mp3' -exec tar -czvf music.tar.gz {} +

排除某个目录

-prune是一个动作项,它表示当文件是一个目录文件时,不进入此目录进行搜索。

-prune经常和-path一起使用,以避开某个目录,常见的形式是:

find PATH -path <dont want> -prune -o -path <want>

find . -path "./sk" -prune -o -name "*.txt" -print
查找当前目录或者子目录下所有.txt文件,但是跳过子目录sk

注意:如果同时使用-depth设置项,那么-prune将被find命令忽略。man手册页中这么说:“If -depth is given, false; no effect.”

实例

//查找当前目录下名为 file.txt 的文件:
find . -name file.txt

//将当前目录及其子目录下所有文件后缀为 .c 的文件列出来:
find . -name "*.c"

//将当前目录及其子目录中的所有文件列出:
find . -type f

//查找 /home 目录下大于 1MB 的文件:
find /home -size +1M

//查找 /var/log 目录下在 7 天前修改过的文件:
find /var/log -mtime +7

//查找过去 7 天内被访问的文件:
find /path/to/search -atime -7

//在当前目录下查找最近 20 天内状态发生改变的文件和目录:
find . -ctime  20

//将当前目录及其子目录下所有 20 天前及更早更新过的文件列出:
find . -ctime  +20

//查找 /var/log 目录中更改时间在 7 日以前的普通文件,并在删除之前询问它们:
find /var/log -type f -mtime +7 -ok rm {} \;

//查找当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件:
find . -type f -perm 644 -exec ls -l {} \;

//查找系统中所有文件长度为 0 的普通文件,并列出它们的完整路径:
find / -type f -size 0 -exec ls -l {} \;

//找并执行操作(例如删除):
find /path/to/search -name "pattern" -exec rm {} \;
//这个例子中,-exec 选项允许你执行一个命令,{} 将会被匹配到的文件名替代,\; 表示命令结束。

参考

Linux find 命令 | 菜鸟教程

一文详解 | Linux find 命令-腾讯云开发者社区-腾讯云

find命令-CSDN博客

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值