find详解与命令分隔符

4372 字
22 分钟
find详解与命令分隔符

find详解&&命令分隔符#

[TOC]


find命令#

📌 查找文件或者目录

-type#

📌 按照类型查找

f 普通文件 | d 目录 | l 软连接 | b 块设备 | c 字节设备

下面演示的是 fd,当然以上的各种类型都是可以选择的

Terminal window
# 普通文件和目录
# 找出目录下所有的普通文件
[root@Kylin ~]# mkdir oldboy
[root@Kylin ~]# touch oldboy/{1..3}.log
[root@Kylin ~]# touch oldboy/{1..3}.txt
[root@Kylin ~]# touch oldboy/{1..3}.LOG
[root@Kylin ~]# touch oldboy/{1..3}.TXT
[root@Kylin ~]# mkdir oldboy/{1..3}
# 创建目录1,2,3
[root@Kylin oldboy]# find ./ -type f
# 从当前目录下开始查找,所以显示的也是./1.log
./1.log
./2.log
./3.log
./1.txt
./2.txt
./3.txt
./1.LOG
./2.LOG
./3.LOG
./1.TXT
./2.TXT
./3.TXT
[root@Kylin oldboy]# find ./ -type d
# 找出./下的所有目录
./
./1
./2
./3
# 会带上它自己./这个目录

🌰 案例: 找到的文件带路径

Terminal window
'需要绝对路径查找'
[root@Kylin ~]# find /root/oldboy/ -type f
/root/oldboy/1.log
/root/oldboy/2.log
/root/oldboy/3.log
/root/oldboy/1.txt
/root/oldboy/2.txt
# 从/root/oldboy这个路径开始的,自然也是从这个路径开始显示

-name#

📌 按照名称查找文件

Terminal window
# find -name查找的时候,推荐使用双引号 " "
🌰 案例: 查找名称为1.txt
[root@Kylin ~]# find ./ -name "1.txt"
./1.txt
🌰 案例: 查找以.log结尾的文件
[root@shell ~]# touch {1..3}.log
[root@shell ~]# find ./ -name "*.log"
./1.log
./2.log
./3.log

-iname#

Terminal window
# 忽略大小写
🌰 案例: 查找名称为1.txt的不区分大小写
[root@Kylin ~]# find oldboy/ -iname "1.txt"
oldboy/1.txt
oldboy/1.TXT
# 都匹配出来了
🌰 案例: 查找所有以.txt结尾的文件
[root@Kylin ~]# find oldboy/ -iname "*.txt"
# "*.txt" 牢固掌握
# -iname 大小写都匹配
oldboy/1.txt
oldboy/2.txt
oldboy/3.txt
oldboy/1.TXT
oldboy/2.TXT
oldboy/3.TXT

-inum#

📌 find按照inode号查找

Terminal window
[root@oldboy home]# ll -i a.txt
34139649 -rw-r--r-- 1 root root 0 Dec 10 19:05 a.txt
[root@oldboy home]# find / -type f -inum 34139649
/home/a.txt
# 从 /根 找inode号为34139649的文件

-size#

c:字节 以字节为单位,是c,而并非是B,大写 B 表示 Byte是后来更广泛使用的约定,而 find 的语法早在 B 成为通用符号之前就已标准化,为了向后兼容,不能随意更改 k:KB M:MB G:GB

Terminal window
# 按照大小进行查找
[root@Kylin oldboy]# dd if=/dev/zero of=a.txt bs=1M count=5
# 5M
[root@Kylin oldboy]# dd if=/dev/zero of=b.txt bs=1M count=10
# 10M
[root@Kylin oldboy]# dd if=/dev/zero of=c.txt bs=1M count=15
# 15M
[root@Kylin oldboy]# dd if=/dev/zero of=d.txt bs=1M count=20
# 20M
[root@Kylin oldboy]# dd if=/dev/zero of=e.txt bs=1M count=2000
# 2000M → 2G
'生成五个文件大小都不一样'
🌰 案例: 找出等于5M的文件
[root@Kylin oldboy]# find ./ -size 5M
./a.txt
# 刚刚好5M大小,很少用
[root@Kylin oldboy]# ll -h a.txt
-rw-r--r-- 1 root root 5.0M Nov 5 09:53 a.txt
# -5M 小于5M的文件
[root@Kylin oldboy]# find ./ -size -5M
# +5M 大于5M的文件
[root@Kylin oldboy]# find ./ -size +5M
🌰 案例: 查找系统中大于200M的文件
[root@oldboy home]# find / -size +200M
# 专门查找系统中的大文件

📌 企业中磁盘不够用了如何解决?

(1)查找系统中的大文件 (2)有用的文件则备份到服务器中保留 (3)没用删除 (4)增加磁盘

-mtime#

Terminal window
mtime # 按照时间(modify修改时间)查找文件
atime # access访问时间

📌 文件的三种时间:

Access:访问时间 — cat vim less more Modify:修改时间 — vim echo Change:详细文件属性的改变时间

我们来稍微验证一下这个时间:

(1)访问时间

cat vim less more

  • 只有第一次进行访问的时候,这个访问时间会发生改变
  • 可以只有访问时间进行改变
  • 访问时间改变,modify和change可以不变
  • ls -lu 查看的是这个时间

(2)修改时间

vim echo

  • 修改modify时间,change时间一定改变
  • 用echo修改,因为没有查看内容,所以访问时间没有改变
  • vim修改,你修改的同时还看见文件内容,所以三个时间都发生了改变
  • sed -i修改,三个时间也是都发生了改变
  • ls -l 默认查看的就是这个时间

(3)改变时间

详细文件属性的改变时间

  • 我们可以通过 chmod +x 改变权限,来做到只修改change时间
  • modify时间改变,change时间一定改变

Terminal window
# 实验准备: 创建08年的文件
[root@Kylin oldboy]# date -s 20081010
Fri Oct 10 00:00:00 CST 2008
[root@Kylin oldboy]# touch 2008_{1..3}.txt
[root@Kylin oldboy]# ll 2008_{1..3}.txt
-rw-r--r-- 1 root root 0 Oct 10 00:00 2008_1.txt
-rw-r--r-- 1 root root 0 Oct 10 00:00 2008_2.txt
-rw-r--r-- 1 root root 0 Oct 10 00:00 2008_3.txt
[root@Kylin oldboy]# ntpdate ntp1.aliyun.com
# 时间同步!

📌 mtime(是modify修改时间) 📌 atime(是access访问时间)

find / -mtime 0 表示24小时内 find / -mtime -1 表示48小时内 find / -mtime +1 表示48小时前

Terminal window
# 业务每天产生日志文件、日积月累越来越多,服务器只保留最近30天或者7天的内容
🌰 案例: 查找目录下修改时间7天前的文件
[root@Kylin oldboy]# find ./ -mtime +7
# 从0开始算,实际上+6就够用了
./
./2008_1.txt
./2008_2.txt
./2008_3.txt
# 7天前的文件
'这个+7是7天之前,不是-7(7天内)'
🌰 案例: 查找30天前的文件
[root@Kylin oldboy]# find ./ -mtime +30
# +30是30天之前,同理-30一个月之内的
./
./2008_1.txt
./2008_2.txt
./2008_3.txt
# 一个月以前的文件

🧣权限#

选项说明
-perm 644精确权限匹配
-user name属主
-group name属组
Terminal window
# 精确权限匹配
[root@rocky10:~]# chmod 655 a/a.txt
[root@rocky10:~]# find a -type f -perm 655
a/a.txt
# 查找a目录下所有权限为655的文件
'后面直接跟数字即可!'
# 属主用的多一点,属组几乎不用!!
[root@rocky10:~]# find / -type f -user test
# 查找属主为test的所有文件
/home/test/.bash_logout
/home/test/.bash_profile
/home/test/.bashrc
/home/test/.bash_history
find: '/proc/3733/task/3733/fdinfo/6': No such file or directory
find: '/proc/3733/fdinfo/5': No such file or directory
/var/spool/mail/test

-a#

Terminal window
# -a and 并且关系 默认就是-a参数、可以省略
🌰 案例: 找出名称为1的文件
[root@Kylin oldboy]# find ./ -type f -name "1"
# 用-type限制文件类型,否则既能找出文件也能找出目录
🌰 案例: 找出目录并且名字为1
[root@Kylin oldboy]# find ./ -type d -name "1"
# 这个同理 -type d 限制为目录
🌰 案例: 找出大于5M并且小于20M的文件
[root@Kylin oldboy]# find ./ -size +5M -size -20M
./b.txt
./c.txt
# 选项都是一个选项,只是巧妙地运用 + 和 - 来控制范围
[root@Kylin oldboy]# ll -h b.txt c.txt
-rw-r--r-- 1 root root 10M Nov 5 09:53 b.txt
-rw-r--r-- 1 root root 15M Nov 5 09:53 c.txt
# 这两个文件都满足 >5M <20M 的条件

-o#

Terminal window
# -o or 或者关系
🌰 案例: 找出等于5M或者大于500M的文件
[root@Kylin oldboy]# find ./ -size 5M -o -size +500M
# -o 两者满足其一即可
./a.txt
./e.txt
# 没有 + 和 - 就是刚好等于5M, +就是大于500M
[root@Kylin oldboy]# ll -h a.txt e.txt
-rw-r--r-- 1 root root 5.0M Nov 5 09:53 a.txt
# 这个刚好5M
-rw-r--r-- 1 root root 2.0G Nov 5 09:54 e.txt
# 大于500M

-maxdepth#

Terminal window
# -maxdepth 按照深度等级查找文件
# 默认是通过递归将"更深层次"的文件都给查找出来
# -maxdepth 1 不让它递归,只查找1级目录(当前目录)下所有的普通文件
[root@localhost ~]# cd /home
[root@localhost home]# touch a.txt
[root@localhost home]# ll
total 4
-rw-r--r--. 1 root root 0 Mar 4 09:45 a.txt
drwx------. 2 test test 4096 Mar 2 16:17 test
# 一个文件,和一个目录(目录下也有些文件)
[root@localhost home]# touch test/hh.txt
[root@localhost home]# tree ./
./
├── a.txt
└── test
└── hh.txt
2 directories, 2 files
[root@localhost home]# find ./ -type f
# 默认是递归查找出所有的文件的
./test/.bash_logout
./test/.bashrc
./test/.bash_profile
./test/hh.txt
./a.txt
[root@localhost home]# find ./ -maxdepth 1 -type f
./a.txt
# 查找当前目录下的所有文件

find查找小结#

Terminal window
find / -type f
find / -name "1.txt"
find / -name "*.txt"
find / -iname "*.txt"
find / -size 10M
find / -mtime +7
find / -type f -name "1.txt"
find / -size 5M -o -size +100M
find / -mtime +7 -size +100M
# 找出修改时间为7天前,并且大于100M的文件

企业常用的find查找#

(1)查找系统中的大文件(面试题)

✅️ find / -size +500M

(2)按照修改时间查找(笔试题)

查找出目录 /data 下,修改时间大于30天的文件并且删除

find /data -mtime +30 -type f 并且删除我们后面配合其他命令执行

Terminal window
# (1)删除文件
find /var/log/ -type f -name "*.log" -mtime +30 -exec rm -rf {} \;
# (2)打包压缩
find /data -type f -mtime -7 | xargs tar zcf all.tar.gz
[root@localhost ~]# mkdir /data
[root@localhost ~]# touch /data/a.txt
[root@localhost ~]# cd /home/
[root@localhost home]# find /data -type f -mtime -7 | xargs tar zcf all.tar.gz
tar: Removing leading / from member names
[root@localhost home]# ll
total 8
-rw-r--r--. 1 root root 113 Mar 4 12:33 all.tar.gz
# (3)权限修复
# 文件如此,目录也是如此;-type d
find . -type f ! -perm 644 -exec chmod 644 {} \;
# 当前目录下,不是644的文件都改为644
[root@localhost home]# chmod 633 all.tar.gz
[root@localhost home]# ll all.tar.gz
-rw--wx-wx. 1 root root 113 Mar 4 12:33 all.tar.gz
# 633
[root@localhost home]# find . -type f ! -perm 644 -exec chmod 644 {} \;
[root@localhost home]# ll all.tar.gz
-rw-r--r--. 1 root root 113 Mar 4 12:33 all.tar.gz
# 644
# (4)使用 find 命令查找 /data/project 下所有空文件或空目录并删除
[root@localhost ~]# find /data/project/ -empty -exec rm -rf {} \;

🌰 使用 find 命令查找系统中所有属于 appuser 用户的文件(排除 /proc/sys 目录)

Terminal window
[root@localhost ~]# find / \( -path /proc -o -path /sys \) -prune -o -type f -user appuser -print
/var/spool/mail/appuser

🔍 逐部分解释:

  • /:从根开始搜索

  • \( -path /proc -o -path /sys \):匹配路径是 /proc/sys

    • 这里面路径也是 -o(或者),而不是-a
  • -prune:如果匹配成功(即进入 /proc/sys 目录本身),就不递归进入其子目录

  • -o:逻辑”或”,表示”如果不是上面的情况,则执行后面的操作”

  • -type f -user appuser -print:查找普通文件、属主为 appuser,并打印

✅️ 这样写,find 在遇到 /proc/sys 目录时会直接跳过,不会进入其内部,也就不会报错

🧣locate#

特性locatefind
速度⚡ 极快(查数据库)🐢 较慢(遍历磁盘)
实时性❌ 非实时(依赖数据库更新)✅ 实时
搜索条件主要是文件名文件名、类型、大小、时间、权限等
是否需要权限一般不需要(读数据库)需要对目标目录有读权限
新建文件能否找到否(除非先 updatedb
Terminal window
# locate可以实现模糊查询,速度比find快
# 每次开机后,会将学习到的文件路径存到数据库中
# 如果是开机后新创建的文件,默认不在库中,无法查询
# 需要使用updatedb手动更新数据库,或重启机器
[root@rocky10:~]# find / -name "test_api.*"
/root/demo/projects/api/tests/test_api.py
# 卡顿,很慢
[root@rocky10:~]# locate test_api
/root/demo/projects/api/tests/test_api.py
# 很快
[root@rocky10:~]# touch a/1111111.txt
# 新建一个文件
[root@rocky10:~]# find / -name "1111111.txt"
/root/a/1111111.txt
'find能找到'
[root@rocky10:~]# locate 1111111.txt
'locate找不到'
[root@rocky10:~]# updatedb
# 需要手动更新
[root@rocky10:~]# locate 1111111.txt
/root/a/1111111.txt
# 才能找到

配合其他命令执行#

📌 find的结果交给其他命令执行

xargs#

📌 将屏幕上的内容甩到最后面、但是必须符合命令的语法才可以执行

⚠️ 别名失效

xargs cat#

Terminal window
1)创建文件并写入内容
[root@Rocky ~]# echo hehe > test.txt
2)查看文件内容
[root@Rocky ~]# cat test.txt
hehe
3)使用 find 查找文件(相对路径)
[root@Rocky ~]# find ./ -name "test.txt"
./test.txt
4)使用 find + xargs 组合执行命令
[root@Rocky ~]# find ./ -name "test.txt" | xargs cat
hehe
# xargs 将 find 的输出(即 ./test.txt)作为参数传递给 cat,相当于执行 cat ./test.txt

xargs rm#

⚠️ xargs后面的别名失效

  • rm 的别名 rm -i 失效后等价于 \rm 等价于 rm -f
    • 直接强制删除了 —> 没有提示

🌰 案例: 找出所有的 .log 结尾的文件,然后交给 rm 命令

Terminal window
[root@Kylin oldboy]# find ./ -name "*.log" | xargs rm
# 可以把这些都给删除了

xargs ls#

🌰 案例: 查找文件的详细信息

Terminal window
[root@oldboy home]# find ./ -name "test.txt" | xargs ll
xargs: ll: No such file or directory '别名失效'
[root@Kylin oldboy]# find ./ -name "test.txt" | xargs ls -l
-rw-r--r-- 1 root root 5 Nov 5 10:44 ./test.txt
# 这个同理

-i#

-i insert 指定插入

  • 配合 {} 使用,将结果插入到 {} 里面
  • 这个括号必须闭合,不要有空格

🌰 案例: 将查找到的以 .txt 结尾的文件复制到 /opt 目录下

Terminal window
[root@oldboy home]# rm -rf /opt/*
[root@oldboy home]# ll /opt/
total 0
[root@oldboy home]# find ./ -name "*.txt" | xargs -i cp { } /opt/
cp: cannot stat '{': No such file or directory
cp: cannot stat '}': No such file or directory
⚠️ 括号必须闭合
[root@oldboy home]# find ./ -name "*.txt" | xargs -i cp {} /opt/
[root@oldboy home]# ll /opt/
-rw-r--r-- 1 root root 5 Dec 10 12:34 test.txt

-n#

📌 按照列输出

Terminal window
[root@oldboy home]# echo {1..10}
1 2 3 4 5 6 7 8 9 10
[root@oldboy home]# echo {1..10} | xargs -n 1
1
2
3
4
5
6
7
8
9
10
'按照两列输出'
[root@oldboy home]# echo {1..10} | xargs -n 2
1 2
3 4
5 6
7 8
9 10
  • 想生成一行一行的随机IP地址???
    • 使用 xargs 把它一行行的分开写
Terminal window
[root@Rocky ~]# echo 192.168.219.{1..5}
192.168.219.1 192.168.219.2 192.168.219.3 192.168.219.4 192.168.219.5
[root@Rocky ~]# echo 192.168.219.{1..5} | xargs -n1
192.168.219.1
192.168.219.2
192.168.219.3
192.168.219.4
192.168.219.5
'并写入到文件中'
[root@Rocky ~]# echo 192.168.219.{1..5} | xargs -n1 > ip.txt
[root@Rocky ~]# cat ip.txt
192.168.219.1
192.168.219.2
.......

xargs(单独用)#

Tip

xargs -n2 单独用时:分列,分组,分队

⚠️ 后面不能直接跟文件名,需要输入重定向符号 < 连接,再跟文件名

Terminal window
[root@Rocky ~]# xargs -n2 < ip.txt
192.168.219.1 192.168.219.2
192.168.219.3 192.168.219.4
192.168.219.5

综合#

查找到的文件交给cat命令,再交给less命令

Terminal window
[root@Kylin ~]# find /etc -type f -name "services" | xargs cat -n | less
# 配合 | 管道符,非常灵活

(1)先find找出这个文件 (2)cat -n 查看内容 (3)最后用less查看,方便快捷

-exec#

📌 使用-exec

  • ✅️ -execfind 命令的内置动作
    • -exec 并不是只能用在 find 命令中,但最常见、最经典的应用确实是在 find 命令里
  • ❌️ 其他命令通常没有 -exec 选项

⚠️ 别名失效

📌 语法:

Terminal window
find ./ -type f -exec 命令 {} \;
# 类型为 f 文件的
# {} 将find执行的结果指定到{}里面
# \; 撬棍分号 "打回原形"
Terminal window
[root@oldboy home]# ll
total 4
-rw-r--r-- 1 root root 5 Dec 10 12:11 test.txt
# 当前目录下只有一个 test.txt文件
1)交给cat命令
[root@oldboy home]# find ./ -name "test.txt" -exec cat {} \;
hehe
2)交给ls命令
[root@oldboy home]# find ./ -name "test.txt" -exec ll {} \;
find: 'll': No such file or directory
# 直接报错,不支持别名ll
[root@oldboy home]# find ./ -name "test.txt" -exec ls -l {} \;
-rw-r--r-- 1 root root 5 Dec 10 12:11 ./test.txt
# 用ls -l
3)交给cp命令
[root@oldboy home]# find ./ -name "test.txt" -exec cp {} /opt/ \;
[root@oldboy home]# ll /opt/
total 4
-rw-r--r-- 1 root root 5 Dec 10 13:00 test.txt
# 成功复制到/opt/目录下
4)交给rm命令
[root@oldboy home]# find ./ -name "test.txt" -exec rm {} \;
[root@oldboy home]# ll
total 0
# 当前目录下什么都没有了

$() 或 反引号#

Tip

📌 先执行里面的命令 ✅️ 此种方法别名生效!

  • 反引号 ` `$() 在功能上是等价的,它们都用于命令替换
    • 即执行括号内的命令,并将其标准输出作为字符串插入到当前命令行中

😍 但 $() 更推荐,原因如下:

  • 清晰易读
  • 天然支持嵌套
  • 转义规则简单(内部无需特殊转义)

❌️ 反引号 ` `

  • 转义规则复杂(内部需转义反斜杠、反引号等)
  • 可读性较差(尤其在复杂命令中)
  • 嵌套非常困难,需要转义

🌰 案例: 交给cat命令(cp命令、rm命令)

Terminal window
[root@oldboy home]# echo fadfas > test.txt
[root@oldboy home]# find ./ -name "test.txt"
./test.txt
[root@oldboy home]# cat `find ./ -name "test.txt"`
# 反引号(`)执行命令替换
fadfas
[root@oldboy home]# cat $(find ./ -name "test.txt")
# $() 也是命令替换,更推荐
fadfas
# `` 或者 $()
ls -l `find / -type f`
cat `find / -type f`
rm -rf `find / -type f`
cp `find / -type f` /opt/

命令分隔符#

📌 一次可以执行多条命令

;

📌 不管前面的命令是否执行成功、继续往后执行

Terminal window
# ech 故意少写o, touc 故意少写h
[root@Kylin ~]# ech hehe; touc b.txt; cd oldboy
-bash: ech: command not found
-bash: touc: command not found
# 前两个虽然报错,但也还是执行了,只有最后cd oldboy正确
[root@Kylin oldboy]# pwd
/root/oldboy
# 也是成功进来了

&&#

📌 前面的命令必须成功才会往后执行

Terminal window
# 第一个命令就是错的 → 后面都不执行
[root@Kylin ~]# ech hehe && touc b.txt && cd oldboy
-bash: ech: command not found
# 虽然有两个错误,但是只要第一个错,就不往后执行了
# 三个都正确 → 全部执行
[root@Kylin ~]# echo hehe && touch b.txt && cd oldboy
hehe
# 都正确
[root@Kylin oldboy]# pwd
/root/oldboy
# 才能进入到oldboy目录

🌰 案例: 保证网络通、才会继续安装软件

Terminal window
[root@Kylin ~]# ping -c1 -W1 www.baidu.com &>/dev/null && yum -y install wget
# -c1 指定ping的次数
# -W1 设置等待响应的超时时间为1秒
  • &> 无论结果对错都不显示至屏幕
  • && 只有前面ping通了,有网络了才用yum安装

||#

📌 前面命令必须失败才会继续执行

Terminal window
# 三个都正确 → 只执行第一个命令
[root@Kylin ~]# echo a || touch b.txt || cd oldboy
a
# 三个都正确,但是只执行第一个命令
# 前两个都错 → 继续往后直到成功
[root@Kylin ~]# ech a || touc b.txt || cd oldboy
-bash: ech: command not found
-bash: touc: command not found
[root@Kylin oldboy]# pwd
/root/oldboy

混合使用#

Terminal window
# 能ping通 → &&执行echo, ||前面成功所以不执行
[root@Kylin ~]# ping -c1 -W1 www.baidu.com &>/dev/null && echo 网络通 || echo 网络不通
网络通
# 不能ping通 → &&不执行(失败), ||前面失败所以执行echo
[root@Kylin ~]# ping -c1 -W1 www.baiduaaaaa.com &>/dev/null && echo 网络通 || echo 网络不通
网络不通

📌 如果进入test失败则创建test目录、如果能进入则不执行mkdir的动作

Terminal window
[root@oldboy home]# cd test || mkdir test
-bash: cd: test: No such file or directory
# 前面执行失败了 --> 所以创建了test文件夹
[root@oldboy home]# ll
total 0
drwxr-xr-x 2 root root 6 Dec 10 14:36 test '创建成功'
# 还可以再优化,把提示“吃掉”
[root@oldboy home]# cd jiu &> /etc/null || mkdir jiu
[root@oldboy home]# ll
total 0 '成功创建jiu文件夹'
drwxr-xr-x 2 root root 6 Dec 10 14:37 jiu

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

find详解与命令分隔符
https://www.kpyun.fun/posts/basics/core/core09/
作者
久棹
发布于
2025-08-01
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
久棹
只要胆子大,天天寒暑假!
公告
欢迎来到久棹的技术小站!本站专注 Linux 运维学习笔记分享,如有问题欢迎交流探讨 🎉
分类
标签
站点统计
文章
98
分类
11
标签
203
总字数
244,453
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.13.5
文章许可
CC BY-NC-SA 4.0

文章目录