find详解与命令分隔符
find详解&&命令分隔符
[TOC]
find命令
📌 查找文件或者目录
-type
📌 按照类型查找
f普通文件 |d目录 |l软连接 |b块设备 |c字节设备下面演示的是
f和d,当然以上的各种类型都是可以选择的
# 普通文件和目录
# 找出目录下所有的普通文件[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# 会带上它自己./这个目录🌰 案例: 找到的文件带路径
'需要绝对路径查找'[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
📌 按照名称查找文件
# 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
# 忽略大小写
🌰 案例: 查找名称为1.txt的不区分大小写[root@Kylin ~]# find oldboy/ -iname "1.txt"oldboy/1.txtoldboy/1.TXT# 都匹配出来了
🌰 案例: 查找所有以.txt结尾的文件[root@Kylin ~]# find oldboy/ -iname "*.txt"# "*.txt" 牢固掌握# -iname 大小写都匹配oldboy/1.txtoldboy/2.txtoldboy/3.txtoldboy/1.TXToldboy/2.TXToldboy/3.TXT-inum
📌 find按照inode号查找
[root@oldboy home]# ll -i a.txt34139649 -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:KBM:MBG:GB
# 按照大小进行查找[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
mtime # 按照时间(modify修改时间)查找文件atime # access访问时间📌 文件的三种时间:
Access:访问时间 —catvimlessmoreModify:修改时间 —vimechoChange:详细文件属性的改变时间

我们来稍微验证一下这个时间:
(1)访问时间
catvimlessmore
- 只有第一次进行访问的时候,这个访问时间会发生改变
- 可以只有访问时间进行改变
- 访问时间改变,modify和change可以不变
ls -lu查看的是这个时间


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


(3)改变时间
详细文件属性的改变时间
- 我们可以通过
chmod +x改变权限,来做到只修改change时间- modify时间改变,change时间一定改变

# 实验准备: 创建08年的文件[root@Kylin oldboy]# date -s 20081010Fri 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小时前
# 业务每天产生日志文件、日积月累越来越多,服务器只保留最近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 | 属组 |
# 精确权限匹配[root@rocky10:~]# chmod 655 a/a.txt[root@rocky10:~]# find a -type f -perm 655a/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_historyfind: '/proc/3733/task/3733/fdinfo/6': No such file or directoryfind: '/proc/3733/fdinfo/5': No such file or directory/var/spool/mail/test-a
# -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
# -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
# -maxdepth 按照深度等级查找文件# 默认是通过递归将"更深层次"的文件都给查找出来# -maxdepth 1 不让它递归,只查找1级目录(当前目录)下所有的普通文件
[root@localhost ~]# cd /home[root@localhost home]# touch a.txt[root@localhost home]# lltotal 4-rw-r--r--. 1 root root 0 Mar 4 09:45 a.txtdrwx------. 2 test test 4096 Mar 2 16:17 test# 一个文件,和一个目录(目录下也有些文件)[root@localhost home]# touch test/hh.txt[root@localhost home]# tree ././├── a.txt└── test └── hh.txt2 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查找小结
find / -type ffind / -name "1.txt"find / -name "*.txt"find / -iname "*.txt"find / -size 10Mfind / -mtime +7find / -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并且删除我们后面配合其他命令执行
# (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.gztar: Removing leading / from member names[root@localhost home]# lltotal 8-rw-r--r--. 1 root root 113 Mar 4 12:33 all.tar.gz
# (3)权限修复# 文件如此,目录也是如此;-type dfind . -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 目录)
[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
| 特性 | locate | find |
|---|---|---|
| 速度 | ⚡ 极快(查数据库) | 🐢 较慢(遍历磁盘) |
| 实时性 | ❌ 非实时(依赖数据库更新) | ✅ 实时 |
| 搜索条件 | 主要是文件名 | 文件名、类型、大小、时间、权限等 |
| 是否需要权限 | 一般不需要(读数据库) | 需要对目标目录有读权限 |
| 新建文件能否找到 | 否(除非先 updatedb) | 是 |
# 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
1)创建文件并写入内容[root@Rocky ~]# echo hehe > test.txt
2)查看文件内容[root@Rocky ~]# cat test.txthehe
3)使用 find 查找文件(相对路径)[root@Rocky ~]# find ./ -name "test.txt"./test.txt
4)使用 find + xargs 组合执行命令[root@Rocky ~]# find ./ -name "test.txt" | xargs cathehe# xargs 将 find 的输出(即 ./test.txt)作为参数传递给 cat,相当于执行 cat ./test.txtxargs rm
⚠️ xargs后面的别名失效
rm的别名rm -i失效后等价于\rm等价于rm -f
- 直接强制删除了 —> 没有提示
🌰 案例: 找出所有的 .log 结尾的文件,然后交给 rm 命令
[root@Kylin oldboy]# find ./ -name "*.log" | xargs rm# 可以把这些都给删除了xargs ls
🌰 案例: 查找文件的详细信息
[root@oldboy home]# find ./ -name "test.txt" | xargs llxargs: 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
-iinsert 指定插入
- 配合
{}使用,将结果插入到{}里面- 这个括号必须闭合,不要有空格
🌰 案例: 将查找到的以 .txt 结尾的文件复制到 /opt 目录下
[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 directorycp: 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
📌 按照列输出
[root@oldboy home]# echo {1..10}1 2 3 4 5 6 7 8 9 10[root@oldboy home]# echo {1..10} | xargs -n 112345678910'按照两列输出'[root@oldboy home]# echo {1..10} | xargs -n 21 23 45 67 89 10- 想生成一行一行的随机IP地址???
- 使用
xargs把它一行行的分开写
- 使用
[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 -n1192.168.219.1192.168.219.2192.168.219.3192.168.219.4192.168.219.5
'并写入到文件中'[root@Rocky ~]# echo 192.168.219.{1..5} | xargs -n1 > ip.txt[root@Rocky ~]# cat ip.txt192.168.219.1192.168.219.2.......xargs(单独用)
xargs -n2 单独用时:分列,分组,分队
⚠️ 后面不能直接跟文件名,需要输入重定向符号 < 连接,再跟文件名
[root@Rocky ~]# xargs -n2 < ip.txt192.168.219.1 192.168.219.2192.168.219.3 192.168.219.4192.168.219.5综合
查找到的文件交给cat命令,再交给less命令
[root@Kylin ~]# find /etc -type f -name "services" | xargs cat -n | less# 配合 | 管道符,非常灵活(1)先find找出这个文件
(2)cat -n 查看内容
(3)最后用less查看,方便快捷
-exec
📌 使用-exec
- ✅️
-exec是find命令的内置动作
-exec并不是只能用在 find 命令中,但最常见、最经典的应用确实是在 find 命令里- ❌️ 其他命令通常没有
-exec选项⚠️ 别名失效
📌 语法:
find ./ -type f -exec 命令 {} \;# 类型为 f 文件的# {} 将find执行的结果指定到{}里面# \; 撬棍分号 "打回原形"[root@oldboy home]# lltotal 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]# lltotal 0# 当前目录下什么都没有了$() 或 反引号
📌 先执行里面的命令 ✅️ 此种方法别名生效!
- 反引号
` `和$()在功能上是等价的,它们都用于命令替换- 即执行括号内的命令,并将其标准输出作为字符串插入到当前命令行中
😍 但 $() 更推荐,原因如下:
- 清晰易读
- 天然支持嵌套
- 转义规则简单(内部无需特殊转义)
❌️ 反引号 ` `:
- 转义规则复杂(内部需转义反斜杠、反引号等)
- 可读性较差(尤其在复杂命令中)
- 嵌套非常困难,需要转义
🌰 案例: 交给cat命令(cp命令、rm命令)
[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/命令分隔符
📌 一次可以执行多条命令
;
📌 不管前面的命令是否执行成功、继续往后执行
# 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# 也是成功进来了&&
📌 前面的命令必须成功才会往后执行
# 第一个命令就是错的 → 后面都不执行[root@Kylin ~]# ech hehe && touc b.txt && cd oldboy-bash: ech: command not found# 虽然有两个错误,但是只要第一个错,就不往后执行了
# 三个都正确 → 全部执行[root@Kylin ~]# echo hehe && touch b.txt && cd oldboyhehe# 都正确[root@Kylin oldboy]# pwd/root/oldboy# 才能进入到oldboy目录🌰 案例: 保证网络通、才会继续安装软件
[root@Kylin ~]# ping -c1 -W1 www.baidu.com &>/dev/null && yum -y install wget# -c1 指定ping的次数# -W1 设置等待响应的超时时间为1秒
&>无论结果对错都不显示至屏幕&&只有前面ping通了,有网络了才用yum安装
||
📌 前面命令必须失败才会继续执行
# 三个都正确 → 只执行第一个命令[root@Kylin ~]# echo a || touch b.txt || cd oldboya# 三个都正确,但是只执行第一个命令
# 前两个都错 → 继续往后直到成功[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混合使用
# 能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的动作
[root@oldboy home]# cd test || mkdir test-bash: cd: test: No such file or directory# 前面执行失败了 --> 所以创建了test文件夹[root@oldboy home]# lltotal 0drwxr-xr-x 2 root root 6 Dec 10 14:36 test ← '创建成功'
# 还可以再优化,把提示“吃掉”[root@oldboy home]# cd jiu &> /etc/null || mkdir jiu[root@oldboy home]# lltotal 0 '成功创建jiu文件夹'drwxr-xr-x 2 root root 6 Dec 10 14:37 jiu文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!




