问题

Linux 下 find 命令的使用是怎样的?

回答
在 Linux 世界里,寻找文件是件家常便饭的事儿,而 `find` 命令就是那个帮你快速定位目标的神兵利器。它可不像你傻乎乎地一个个目录翻找那么低效,`find` 能以你指定的方式在文件系统中“巡逻”,帮你把藏得再深的文件也揪出来。

别看它名字简单,`find` 的能力可绝不含糊,它可以根据文件名、大小、修改时间、文件类型、权限等等各种条件来搜索。下面咱们就来掰扯掰扯,看它到底有多牛。

`find` 命令的基本套路

`find` 命令的基本语法是这样的:

```bash
find [搜索路径] [选项] [动作]
```

搜索路径 (search path): 这是 `find` 命令开始搜索的目录。你可以指定一个或多个目录。如果省略,它默认会在当前目录(`.`)开始搜索。
选项 (options): 这些是用来告诉 `find` 应该搜索什么、怎么搜索的规则。比如,你想按名字搜,或者按大小搜,这些都得靠选项来定义。
动作 (actions): 当 `find` 找到符合条件的文件时,你希望对它做什么?是打印出来,还是删除,还是执行某个命令?这就需要动作来指定了。最常用的动作就是打印出文件名。

深入剖析:选项和动作

咱就从最核心的 选项 和 动作 说起。

一、 最常用的选项:按名字找

想找个叫 `myfile.txt` 的文件?这最简单,用 `name` 选项:

```bash
find . name myfile.txt
```

这会在当前目录(`.`)及其所有子目录里找名字完全匹配 `myfile.txt` 的文件。

大小写敏感性: `find` 默认是区分大小写的。如果你想找 `MyFile.txt` 或者 `MYFILE.TXT`,可以用 `iname`(insensitive name):

```bash
find . iname myfile.txt
```

通配符大法: 光找固定名字太局限了,通配符才是王道。
``: 匹配任意数量的任意字符(包括零个)。比如,找所有 `.txt` 文件:

```bash
find . name ".txt"
```
注意: 这里的通配符要用引号括起来,防止 shell 在 `find` 命令执行前就替你把通配符展开了。

`?`: 匹配任意一个字符。比如,找 `file1.txt` 和 `file2.txt`:

```bash
find . name "file?.txt"
```

`[]`: 匹配括号内的任意一个字符。比如,找 `fileA.txt` 或 `fileB.txt`:

```bash
find . name "file[AB].txt"
```
你还可以用范围,比如 `[09]` 匹配任意一个数字。

按路径名匹配: 除了文件名,你还可以按整个路径(包括目录名)来匹配,用 `path`:

```bash
find /home/user/documents path "backup/.log"
```
这会找到 `/home/user/documents` 目录及其子目录中,路径里包含 `backup` 目录且文件是 `.log` 结尾的。`ipath` 则忽略大小写。

二、 按文件类型找

有时候你知道要找的是个目录,或者是个符号链接,这时候用 `type` 选项就方便了:

`f`: 普通文件 (file)
`d`: 目录 (directory)
`l`: 符号链接 (symbolic link)
`b`: 块设备文件 (block device)
`c`: 字符设备文件 (character device)
`p`: 管道文件 (named pipe, FIFO)
`s`: 套接字文件 (socket)

举个例子,找当前目录下所有的目录:

```bash
find . type d
```

找所有符号链接:

```bash
find /usr/local/bin type l
```

三、 按时间找

文件最后被访问、修改或状态改变的时间,都是重要的搜索依据。

访问时间 (`atime`): 多少天前被访问过。
`atime n`: 恰好 `n` 天前被访问过。
`atime +n`: 超过 `n` 天前被访问过(即 `n+1` 天或更早)。
`atime n`: 在 `n` 天之内被访问过(即 `n1` 天或更近)。

修改时间 (`mtime`): 文件内容被修改的时间。用法同 `atime`。

状态改变时间 (`ctime`): 文件的元数据(如权限、所有者、链接数等)发生变化的时间。用法同 `atime`。

举个例子,找过去 7 天内被修改过的文件:

```bash
find . mtime 7
```

分钟为单位的查找 (`amin`, `mmin`, `cmin`): 如果你需要更精细的时间控制,可以使用分钟为单位的选项。例如,找过去 60 分钟内修改过的文件:

```bash
find . mmin 60
```

四、 按大小找

文件大小也是一个非常常用的搜索条件。

`size n`: 查找大小为 `n` 的文件。单位默认为 512 字节块。
`+n`: 大于 `n` 个单位。
`n`: 小于 `n` 个单位。

单位还可以指定,非常方便:
`c`: 字节 (bytes)
`k`: 千字节 (kilobytes)
`M`: 兆字节 (megabytes)
`G`: 吉字节 (gigabytes)

例子:
查找大于 10MB 的文件:

```bash
find . size +10M
```

查找小于 1KB 的文件:

```bash
find . size 1k
```

查找大小正好是 100 个字节的文件:

```bash
find . size 100c
```

五、 按权限找

你可以根据文件的权限来搜索。

`perm mode`: 精确匹配权限 `mode`。例如,`perm 644` 查找权限为 `rwrr` 的文件。
`perm mode`: 权限 `mode` 中的所有位都必须设置。例如,`perm 644` 查找那些至少有 `rwrr` 权限的文件,也就是说,文件所有者有读写权限,同组用户有读权限,其他用户有读权限。
`perm /mode`: 权限 `mode` 中任何一位被设置。例如,`perm /222` 查找那些对所有人都有写权限(即 `ugo+w`)的文件。

举个例子,找那些所有者具有执行权限的文件:

```bash
find . perm /u=x
```

或者找那些所有者拥有读写执行权限,而组用户和其他人只有读权限的文件(即 `rwxrr`):

```bash
find . perm 744
```

六、 按用户和组找

查找某个用户或组拥有的文件:

`user username`: 查找用户名为 `username` 的文件。
`group groupname`: 查找组名为 `groupname` 的文件。
`uid n`: 查找用户 ID 为 `n` 的文件。
`gid n`: 查找组 ID 为 `n` 的文件。
`nouser`: 查找那些不属于任何已知的用户的文件(可能是因为用户被删除了)。
`nogroup`: 查找那些不属于任何已知组的文件。

例子:
查找当前用户(`$USER` 变量代表当前登录用户)的所有文件:

```bash
find . user $USER
```

查找所有者是 `root` 的文件:

```bash
find /etc user root
```

查找那些拥有者已经被删除的文件:

```bash
find /home nouser
```

七、 深度控制 (`maxdepth`, `mindepth`)

有时你不想让 `find` 递归得太深,或者只想在特定深度范围内搜索。

`maxdepth levels`: 最大搜索深度。`0` 表示仅当前目录,`1` 表示当前目录及下一级目录,以此类推。

```bash
find . maxdepth 1 type f 只找当前目录下的文件
```

`mindepth levels`: 最小搜索深度。`1` 表示从当前目录的下一级开始搜索,以此类推。

```bash
find . mindepth 2 name ".conf" 只找当前目录下一级以下的 .conf 文件
```

八、 组合条件:逻辑运算符

`find` 命令支持 AND, OR, NOT 来组合多个条件,让搜索更加灵活。

AND (默认): 如果你不指定任何逻辑运算符,条件之间默认是 AND 关系。
```bash
find . type f name ".txt" size +1M 找当前目录下,大小超过 1M 的 .txt 文件
```
这等同于:
```bash
find . type f a name ".txt" a size +1M
```

OR (`o` 或 `or`): 匹配任一条件即可。

```bash
find . name ".txt" o name ".log" 找 .txt 或 .log 文件
```

NOT (`!` 或 `not`): 取反条件。注意: `!` 前面一定要有一个空格,或者用 `not`。

```bash
find . ! name ".txt" 找所有不是 .txt 的文件
```
或者:
```bash
find . not name ".txt"
```

分组 (`(...)`): 使用括号来控制条件的优先级。括号需要用反斜杠转义,因为括号本身在 shell 中有特殊含义。

```bash
find . ( name ".jpg" o name ".png" ) size +500k
找大小超过 500k 的 JPG 或 PNG 图片
```

九、 重头戏:动作 (Actions)

找到文件之后,你想对它做什么?这就是动作的用武之地。

`print` (默认动作): 打印匹配文件的完整路径到标准输出。如果你什么动作都不指定,`find` 默认就会执行 `print`。

```bash
find . name ".txt" print
```
你也可以明确写出来,当你有其他动作时,如果还想打印文件名,就得加上 `print`。

`ls`: 以 `ls dils` 的格式打印文件信息,包括 inode 号、权限、硬链接数、所有者、组、大小、修改时间等。

```bash
find . type f size +100M ls
```

`delete`: 删除匹配到的文件。这个动作非常危险!请务必小心使用,先用 `print` 或 `ls` 确认匹配项无误后再执行!

```bash
find . name ".tmp" type f delete 删除所有 .tmp 文件
```

`exec command {} ;`: 这是最强大也最常用的动作之一。它允许你对找到的每个文件执行一个任意的 shell 命令。
`command`: 你要执行的命令。
`{}`: 这个特殊的符号代表当前找到的文件名。
`;`: 命令的结束符。注意这里的分号前有一个反斜杠,用于防止 shell 提前解释分号。

举例:
给所有 `.sh` 文件添加执行权限:

```bash
find . name ".sh" exec chmod +x {} ;
```

将所有 `.txt` 文件复制到 `/backup` 目录:

```bash
find . name ".txt" exec cp {} /backup/ ;
```

`exec command {} +`: 这个与 `;` 类似,但更高效。它会将多个找到的文件名一次性传递给命令,而不是一个一个地执行命令。这在执行像 `rm`、`cp`、`tar` 这样的命令时非常有用,可以减少命令执行的次数,提高效率。

```bash
find . name ".txt" exec rm {} + 删除所有 .txt 文件,比 ; 版本效率更高
```

`ok command {} ;`: 和 `exec ... ;` 类似,但会在执行每个命令之前,会提示你确认是否执行。这比 `delete` 更安全。

```bash
find . name ".bak" ok rm {} ;
每次删除一个 .bak 文件都会让你确认
```

实际应用中的一些小技巧和注意事项

1. 安全第一: 在使用 `delete` 或 `exec` 执行删除、修改等危险操作前,一定要先用 `print` 或 `ls` 确认你的搜索条件能够准确地匹配到你想要操作的文件。你可以先运行一遍,看看输出是不是你期望的。
2. 性能考虑: 当搜索大量文件时,`exec command {} +` 通常比 `exec command {} ;` 效率更高。
3. 文件句柄限制: 如果你搜索的文件非常多,并且对它们执行某个操作(比如打开、重命名等),要注意系统对打开文件句柄的数量限制。`find` 命令本身不会直接碰到这个问题,但如果你用 `exec` 执行的命令会大量占用资源,就需要注意了。
4. 文件名中的特殊字符: 文件名中可能包含空格、换行符或其他特殊字符。`print0` 动作可以将找到的文件名用空字符 (``) 分隔,这对于配合 `xargs 0` 使用非常安全,可以避免文件名中的空格等导致解析错误。

```bash
find . name " " print0 | xargs 0 rm 删除包含空格的文件名
```
这里的 `xargs 0` 会以空字符作为分隔符来接收输入。

5. 不要在搜索路径中使用通配符: `find /path/` 这样的写法,shell 会先尝试展开 `/path/`,然后再将结果传递给 `find`。这可能导致意外的结果,特别是当匹配的文件很多时。应该写成 `find /path/`。

总结一下

`find` 命令就像你在 Linux 文件系统里训练有素的侦探,给它一个案发现场(搜索路径),再告诉它这个“嫌疑犯”(文件)长什么样(各种条件选项),它就能立刻锁定目标,然后按你的吩咐行动(动作)。

从简单的按名字搜索,到复杂的按时间、大小、权限组合,再到执行任意命令,`find` 的灵活性和强大功能足以应对绝大多数文件查找和管理的需求。熟练掌握 `find` 命令,能极大地提高你在 Linux 下的工作效率,让你事半功倍。多试试,多练习,你会发现它真是个好帮手!

网友意见

user avatar

在 Linux 系统使用中,作为一个管理员,我希望能查找系统中所有的大小超过 200M 文件,查看近 7 天系统中哪些文件被修改过,找出所有子目录中的可执行文件,这些任务需求find命令都可以轻松胜任。

在 Linux 系统文件中常用的属性可以分为以下内容:名称、大小、权限、属主、修改时间、访问时间等,find 命令可以按照指定的属性为条件进行查找。

废话不多,直接开干,下边进入案例实战。

案例实战

(一)按文件名称查找

按照文件名称查找是 find 最常见的用法,需要注意的是,搜索的文件名必须完全匹配,才能找到对应的文件。

1. 查找当前目录下所有 go 文件

       $ find . -name "*.go"     

2.在 etc 目录下,查找大写字母开头的 txt 文件

       $ find /etc -name "[A-Z]*.txt" -print     

3.在当前目录下查找不是 out 开头的 txt 文件

       $ find . -name "out*" -prune -o -name "*.txt" -print     

4.在当前目录除 git 子目录外查找 txt 文件

       $ find . -path "./git" -prune -o -name "*.txt" -print     

5.找出某个文件的所有硬链接,ls 命令-i选项可以查看文件的 inode 号

       $ ls -i 1.txt 138956 1.txt $ find . -num 138956     

搜索文件时使用 -iname 参数可以忽略文件名称大小写

(二)按文件类型查找

1. 在当前目录下,查找软连接文件

       $ find . -type l -print     

2.在当前目录下,查找 log 结尾的普通文件,f表示普通文件类型

       $ find . -type f -name "*.log"     

(三)按文件大小查找

1. 查找小于 64k 的文件

       $ find . -size -64k -print     

2.查找大小超过 200M 的文件

       $ find . -size +200M -type f -print     

(四)按时间查找

1. 查找 2 天内被修改过的文件

       $ find . -mtime -2 -type f -print     

2.查找 2 天前被更改过的文件,-mtime表示内容修改时间

       $ find . -mtime +2 -type f -print     

3.查找一天内被访问的文件,-atime表示访问时间

       $ find . -atime -1 -type f -print     

4.查找一天内状态被改变的文件,-ctime表示元数据被变化时间

       $ find . -ctime -1 -type f -print     

5.查找比 chopin.txt 新的文件

       $ find . -newer "chopin.txt" -type f -print $ find . ! -newer "chopin.txt" -type f -print # 旧     

(五)根据权限查找

1. 查找当前目录权限为 644 的文件

       $ find . -type f -perm 644     

2.查找 etc 目录下至少有一个用户有写权限的文件

       $ find /etc -type f -perm /222     

3.查找 etc 目录下所有用户都有执行权限的文件

       $ find /etc -perm -111 -ls     

(六)组合条件

1. 查找当前目录下属于 chopin 用户的普通文件,-a 可以省略

       $ find . -type f -a -user chopin -print     

2.查找当前目录下大于 2M 或 2 天前被修过的文件

       $ find . -size +2M -o -mtime +2 -print     

3.查找当前目录下不是普通文件

       $ find . -not -type f $ find . ! -type f     

4.查找非空文件

       $ find . ! -empty     

(七)处理动作

find 根据上述各种条件查找后,支持执行相关的处理动作,可以让我们的更方便和灵活,而不只是打印出来

1. -print 默认为打印,可省略

       $ find . -name "*.log" -print $ find . -name "*.log" # 等价     

2.-ls以 ls 长文件的格式形式输出

       $ find . -name "*.txt" -ls 138957      4 -rw-r--r--   1 root     root           16 Jan 24 23:20 ./a.txt 138959      4 -rw-r--r--   1 root     root          172 Jan 24 13:06 ./T.txt 138956      4 -rw-r--r--   1 root     root           27 Jan 24 23:28 ./1.txt     

3.-delete删除查找到的文件

       $ find . -size +100M -delete     

4.-exec将查找到的文件传递给 command 命令。下边例子是将查找到的文件传递给了 ls 命令,同理我们可以传递给任何一个 Linux 命令,功能十分强大,也很灵活。

       $ find . -name "*.txt" -exec ls -lh {} ; -rw-r--r-- 1 root root 16 Jan 24 23:20 ./a.txt -rw-r--r-- 1 root root 172 Jan 24 13:06 ./T.txt -rw-r--r-- 1 root root 27 Jan 24 23:28 ./1.txt     

5. -ok-exec 功能一样,只是操作时会提示用户确认,仅此而已。当然,在生产环境上,我们还是推荐使用 ok

(八)经典案例

如果存在一个名称乱码的文件,想要删除它,该怎么办?即使我们复制乱码名称到命令行,很有可能终端不能正确识别。不用担心,下边来展示下 find 是如何优雅的解决问题的。

       $ ls  -i 138957 a.txt  138959 T.txt  132395  ��.txt  $ find . -inum 132395 -exec rm {} ;     

命令中,-inum指定的是文件的inode号,它是系统中每个文件对应的唯一编号,find 通过编号找到后,执行删除操作。

总结归纳

find 命令是 Linux 命令中最有用的命令之一,它的功能非常强大,且语法复杂。其实我们不一定需要了解它的所有细节,掌握上述实战案例中的常见用法,足够满足日常工作中的大部分需求。

下边我们一起来总结下 find 命令常见用法,加深对 find 使用方法的理解。

命令格式

find path -option [-exec ...]

按文件名查找

  • -name:按照文件名称查找,准确匹配;
  • -iname:不区分文件名的大小写;
  • -inode:按照文件 inode 号查找;

按照文件类型查找

按照文件类型查找,可以使用 -type 选项,具体支持的文件类型如下:

  • f:普通文件
  • d:目录文件
  • l:链接文件
  • s:套接字文件
  • p:管道文件
  • b:块设备文件,比如:磁盘
  • c:字符设备文件,比如:键盘、鼠标、网卡

按照文件从属关系查找

  • -user:以用户名查找
  • -group:以组名查找
  • -uid:以用户 ID 查找
  • -gid:以组 ID 查找
  • -nouser:查找没有属主的文件
  • -nogroup:查找没有属组的文件

按照文件大小查找

按照文件大小查找功能十分常用,用 -size 选项,选项后边指定大小 1024M,表示大小的格式有如下几种:

  • -5M:查找小于 5M 的文件
  • +5M:查找大于 5M 的文件
  • 5M:查找大小为 5M 的文件

单位支持的有 c(字节)kMG 等,需要注意的是默认单位并不是字节,而是 b,大小为 512 字节。

按照时间查找

按照时间查找的功能对系统管理员来说,十分常用,find 支持如下几种时间类型:

  • atime:以访问时间查找
  • mtime:以数据修改时间查找
  • ctime:以元数据修改时间查找
  • newer:以文件为条件,判断比它新的文件

按时间查找时,使用格式如下:

  • -atime -5:表示 5 天内访问过的文件;
  • -atime +5:表示 6 天前访问过的文件;
  • -atime 5:表示前 5-6 那一天访问的文件;

这个 +5 含义总是被人理解错,误认为是 5 天后修改的文件,如果能知道未来 5 天的事情,小编早就去买彩票了!可能这么说还不是很清楚,直接看图吧!

find 不仅可以按 为单位来查找文件,可以按照 aminmmincmin 来查找,区别只是 min 选项单位为分钟。

按照权限查找

按权限查找是通过 -perm 选项,可以按照如下方式使用:

  • -perm 644:精确权限查找
  • -perm /666:任何一类用户中的任何一位符合条件即满足
  • -perm -222:每一类用户的每一位同时符合条件即满足

组合条件

find 可以使用多个条件的组合,支持 -a-o-not!,比较简单,不再详细描述其含义。

处理动作

find 根据各种条件查找后,支持执行相关的处理动作,可以让我们的更方便和灵活,而不只是打印出来。

  • -print:打印,默认动作,可省略
  • -ls:以 ls 长文件格式输出
  • -delete:删除查找到的文件
  • -exec:查找到的文件传递给任何 Linux 命令
  • -ok:与 exec 功能相同,区别是需要用户确认每次的操作

再啰嗦一下,find 命令支持的参数和选项比较多,文中只是总结出最常用、核心的参数选项。如果上述命令确实不满足需求,可以请教你的男人 man find

这里需要提一下,find 搜索文件时通过扫描磁盘来进行的,尽可能不要大范围的搜索文件,尤其是在 / 目录下搜索,会长时间消耗服务器的 cpu 资源。如果是生产环境的机器,执行前要考虑是否会对业务造成影响。

扩展 locate

虽然 find 功能非常强大,但要知道的是,find 执行过程是通过扫描磁盘文件来进行查找的,如果大范围的查找文件,需要花费的时间很长,且消耗服务器 cpu 资源。

这里推荐另一个 Linux 文件查找神器 locate,类似于 win 平台下的 everything。它基于索引表进行查询,查询速度非常快,基本不占用 cpu 资源。

使用方法非常简单

       $ locate file.txt $ locate /etc/httpd     

需要注意,如果是当天新创建的文件,通过 locate 默认是查不到的,因为它的数据库默认是每天自动更新一次。如果希望查询到当天创建的新文件,需要执行 updatedb 即可。

查找速度快是 locate 的优势,但它的缺点也非常明显:

  • 模糊查询
  • 查找匹配模式单一
  • 查询的名称匹配路径命令
  • 索引表的建立会占用磁盘空间
  • 非实时查询,当天数据可能查不到

好了,到这里关于 find 命令的全部内容已经结束,希望文中的案例和总结能够帮助你更好的使用它。同时也强烈建议收藏本文,以作为 Linux 常用命令手册。

作者 | 肖邦
来源 | Linux 文件搜索神器 find 实战详解,建议收藏! (qq.com)

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有