文件查找工具locate和find
文章目录
- 1、locate
- 1.1、搜索语法
- 1.2、创建选项
- 1.3、搜索报错处理
- 1.4、处理办法(创建数据库)
- 1.5、文件搜索
- 1.6、使用正则表达式搜索 -r
- 1.7、局限性
- 2、find
- 2.1、指定目录层级
- 2.1.1、-maxdepth
- 2.1.2、-mindepth
- 2.2、根据文件名和inode查找
- 2.3、根据属主、属组查找
- 2.3.1、-user
- 2.3.2、-nouser
- 2.4、根据文件类型查找
- 2.5、空文件或目录
- 2.6、组合条件
- 2.7、排除目录 -prune
- 2.8、根据文件大小来查找
- 2.8.1、-size
- 2.9、根据文件大小来查找
- 2.10、根据权限查找
- 2.11、处理动作
- 2.11.1、-print
- 2.11.2、 -fls file
- 2.11.3、-delete
- 2.11.4、-ok COMMAND {} \;
- 2.11.5、-exec COMMAND {} \;
- 2.12、参数替换 xargs
1、locate
locate是在磁盘上搜索文件的工具,搜索速度非常快,它的逻辑是在数据库中进行搜索文件索引,并不是去具体的目录里一个一个的找,这就有一个缺陷,就是新建的文件它是搜索不到的。它不会自动更新数据库,这个命令适合搜索那些固定的文件,优点就是搜索速度很快,属于非实时查找。实时查找可以用find命令。
locate
查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db- 索引的构建是在系统较为空闲时自动进行(周期性任务),执行 updatedb 可以更新数据库
- 索引构建过程需要遍历整个根文件系统,很消耗资源
locate
和 updatedb命令来自于mlocate包
工作特点:
- 查找速度快
- 模糊查找
- 非实时查找
- 搜索的是文件的全路径,不仅仅是文件名
- 可能只搜索用户具备读取和执行权限的目录
1.1、搜索语法
locate 要搜索的文件名,可以不写全
1.2、创建选项
**-i 不区分大小写的搜索
-n N 只列举前N个匹配项目
-r 使用基本正则表达式**
1.3、搜索报错处理
如果是首次搜索如果有报错,如下:
[root@VM-20-17-centos ~]# locate shadow
locate: can not stat () '/var/lib/mlocate/mloacte.db': No such file or directory
1.4、处理办法(创建数据库)
**# 新建数据库,这个命令就是把硬盘上的数据库建立索引放到数据库中,命令如下:**
[root@VM-20-17-centos ~]# updatedb
**# 查看是否生产数据库**
[root@VM-20-17-centos ~]# ll /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 2542178 Dec 14 20:35 /var/lib/mlocate/mlocate.db
1.5、文件搜索
**# 这里只是到文件名的前部分是 nginx_ ,后边的不知道是什么了,相当于可以模糊搜索**
[root@VM-20-17-centos shell]# locate nginx_
/root/nginx-1.24.0/src/os/win32/nginx_icon16.xpm
/root/nginx-1.24.0/src/os/win32/nginx_icon32.xpm
/root/nginx-1.24.0/src/os/win32/nginx_icon48.xpm
/root/shell/nginx_log.py
/root/shell/nginx_log.sh
这里有个缺陷,如果是在 updatedb
后建的文件,它是搜索不到的,它是不会自动更新数据库的,如果需要搜索到,需要在执行下 updatedb
来更新数据库索引。
例1:
**# 新建一个12345.txt的文件**
[root@VM-20-17-centos shell]# echo 12345 > 12345.txt
**# 使用 locate 搜索,无法搜索到该文件**
[root@VM-20-17-centos shell]# locate 12345.txt
**# 更新数据库索引,可以正常搜索到该文件了**
[root@VM-20-17-centos shell]# updatedb
[root@VM-20-17-centos shell]# locate 12345.txt
/root/shell/12345.txt
1.6、使用正则表达式搜索 -r
**# 搜索以.conf结尾的文件**
[root@VM-20-17-centos ~]# locate -r '\.conf$'
/app/httpd-2.4.43/docs/doxygen.conf
/app/httpd-2.4.43/docs/conf/httpd.conf
/app/httpd-2.4.43/docs/conf/extra/httpd-autoindex.conf
/app/httpd-2.4.43/docs/conf/extra/httpd-dav.conf
/app/httpd-2.4.43/docs/conf/extra/httpd-default.conf
/app/httpd-2.4.43/docs/conf/extra/httpd-info.conf
......
1.7、局限性
如果删除或者新增需要执行 updatedb
命令,否则无法搜索到。
**# 上文中提到了新增文件,这里测试删除文件,发现还能搜索的到,除非在执行下**updatedb命令
[root@VM-20-17-centos shell]# rm -rf 12345.txt
[root@VM-20-17-centos shell]# locate 12345.txt
/root/shell/12345.txt
**# 执行 updatedb 命令**
[root@VM-20-17-centos shell]# updatedb
[root@VM-20-17-centos shell]# locate 12345.txt
2、find
find 是实时查找工具,通过遍历指定路径完成文件查找。
工作特点:
- 查找速度略慢
- 精确查找
- 实时查找
- 查找条件丰富
- 可能只搜索用户具备读取和执行权限的目录
格式:
find [OPTION]... [查找路径] [查找条件] [处理动作]
查找路径:指定具体目标路径;默认为当前目录。
**查找条件:**指定的查找标准,可以文件名、大小、类型、权限等标准进行;默认为找出指定路径下的所有文件。
**处理动作:**对符合条件的文件做操作,默认输出至屏幕。
例1:
如果只写一个find,它会把当前目录极其所有子目录中的文件全部列一出来。
[root@VM-20-17-centos shell]# find
.
./fstab
./grub
./nginx_log.py
./selinux
./err_nginxlog.sh
./b.txt
./nginx_log.sh
./test
./test/ft.txt
./test/fq.txt
./test/fI.txt
./test/fH.txt
./test/fW.txt
./test/fk.txt
./test/fJ.txt
./test/test2
./test/test2/e.txt
......
2.1、指定目录层级
**-maxdepth level** 最大搜索目录深度,指定目录下的文件为第1级
**-mindepth level** 最小搜索目录深度
2.1.1、-maxdepth
**# 这里我们指定了最大深度为 1 级,其实 etc 目录本身就是 1 级,所以只会搜索etc目录的文件及
目录,包含隐藏文件**
[root@VM-20-17-centos ~]# find /etc/ -maxdepth 1
/etc/
/etc/rshim.conf
/etc/group
/etc/rc6.d
/etc/audit
/etc/rdma
/etc/mailcap
/etc/login.defs.rpmnew
/etc/opt
/etc/img_version
/etc/sysctl.conf
/etc/depmod.d
/etc/ssl
/etc/hosts.deny
......
**# 如果是 2 级,它会搜索 etc 第一层级的子目录及其下边的文件和目录**
[root@VM-20-17-centos ~]# find /etc/ -maxdepth 2
/etc/
/etc/rshim.conf
/etc/group
/etc/rc6.d
/etc/audit
/etc/audit/audit.rules
/etc/audit/audit-stop.rules
/etc/audit/rules.d
/etc/audit/auditd.conf
/etc/rdma
/etc/rdma/modules
......
**# 如果在etc目录中,可以使用如下写法**
[root@VM-20-17-centos etc]# find ./ -maxdepth 1
./
./rshim.conf
./group
./rc6.d
./audit
./rdma
./mailcap
./login.defs.rpmnew
./opt
./img_version
./sysctl.conf
./depmod.d
./ssl
./hosts.deny
......
2.1.2、-mindepth
**# 列出所有文件,我们第二级的只有test目录**
[root@VM-20-17-centos shell]# ll
total 48
-rw-r--r-- 1 root root 105 Dec 4 20:33 a.txt
-rw-r--r-- 1 root root 419 Dec 4 20:35 b.txt
-rwxr-xr-x 1 root root 304 Dec 4 21:18 err_nginxlog.sh
-rwxr-xr-x 1 root root 409 Dec 4 22:32 errnginx.sh
-rw-r--r-- 1 root root 95 Dec 13 19:34 fstab
-rw-r--r-- 1 root root 313 Dec 13 19:19 fstab.bak
-rw-r--r-- 1 root root 307 Dec 14 12:06 grub
-rw-r--r-- 1 root root 293 Dec 14 11:24 grub.bak
-rwxr-xr-x 1 root root 1832 Dec 8 16:52 nginx_log.py
-rwxr-xr-x 1 root root 818 Dec 8 16:54 nginx_log.sh
-rw-r--r-- 1 root root 541 Dec 13 23:15 selinux
drwxr-xr-x 4 root root 4096 Dec 14 21:40 test
[root@VM-20-17-centos shell]# tree
.
|-- a.txt
|-- b.txt
|-- err_nginxlog.sh
|-- errnginx.sh
|-- fstab
|-- fstab.bak
|-- grub
|-- grub.bak
|-- nginx_log.py
|-- nginx_log.sh
|-- selinux
`-- test
|-- test1
| |-- rc0.d
| |-- rc1.d
| |-- rc2.d
| |-- rc3.d
| |-- rcabc
| |-- rc.abc
| `-- rc.d
`-- test2
|-- a.txt
|-- b.txt
|-- c.txt
|-- d.txt
|-- e.txt
|-- test2.conf
`-- test.conf
3 directories, 25 files
如果只想显示第二级的,使用如下写法:
**# 从上述文件列表中第二级只有这两个目录**
[root@VM-20-17-centos shell]# find ./ -maxdepth 2 -mindepth 2
./test/test2
./test/test1
**# 使用绝对路径搜索也是一样的**
[root@VM-20-17-centos shell]# find /root/shell/ -maxdepth 2 -mindepth 2
/root/shell/test/test2
/root/shell/test/test1
2.2、根据文件名和inode查找
**-name** "文件名称":支持使用glob,如:*, ?, [], [^],通配符要加双引号引起来
**-iname** "文件名称":不区分字母大小写
**-inum n** 按inode号查找
**-samefile name** 相同inode号的文件
**-links n** 链接数为n的文件
**-regex “PATTERN”:** **#以PATTERN匹配整个文件路径,而非文件名称**
例1:
**# 查找 etc 下的 passwd 文件**
[root@VM-20-17-centos ~]# find /etc -name passwd
/etc/passwd
/etc/pam.d/passwd
**# 查找 etc 下以 conf 结尾的文件**
[root@VM-20-17-centos ~]# find /etc -name "*.conf"
/etc/rshim.conf
/etc/audit/auditd.conf
/etc/sysctl.conf
/etc/depmod.d/kernel-mft-mst_pciconf.conf
/etc/depmod.d/kvdo.conf
/etc/depmod.d/dist.conf
/etc/depmod.d/kernel-mft-mst_pci.conf
/etc/prelink.conf.d/fipscheck.conf
/etc/prelink.conf.d/grub2.conf
/etc/prelink.conf.d/nss-softokn-prelink.conf
/etc/firewalld/firewalld.conf
/etc/ntp.conf
/etc/libuser.conf
......
正则表达式写法
**# 如果直接这样写是匹配不到的**
[root@VM-20-17-centos ~]# find /etc -regex "*.\.conf$"
**# 需要把前边也匹配上,前边是什么不知道,所以就是 .* ,.conf中的 "." 需要用 "\" 进行转意,
以什么结尾需要在结尾加上$符号**
[root@VM-20-17-centos ~]# find /etc -regex ".*\.conf$"
/etc/rshim.conf
/etc/audit/auditd.conf
/etc/sysctl.conf
/etc/depmod.d/kernel-mft-mst_pciconf.conf
/etc/depmod.d/kvdo.conf
/etc/depmod.d/dist.conf
/etc/depmod.d/kernel-mft-mst_pci.conf
/etc/prelink.conf.d/fipscheck.conf
/etc/prelink.conf.d/grub2.conf
/etc/prelink.conf.d/nss-softokn-prelink.conf
/etc/firewalld/firewalld.conf
/etc/ntp.conf
......
**# 用正则表达式没必要,我们直接通通配符更简单**
root@VM-20-17-centos ~]# find /etc -name "*.conf"
2.3、根据属主、属组查找
**-user USERNAME:**查找属主为指定用户(UID)的文件
**-group GRPNAME:** 查找属组为指定组(GID)的文件
**-uid UserID:**查找属主为指定的UID号的文件
**-gid GroupID:**查找属组为指定的GID号的文件
**-nouser:**查找没有属主的文件
**-nogroup:**查找没有属组的文件
2.3.1、-user
查找属主为指定用户(UID)的文件
例1:
查找gxy的文件
**# 在 var 目录下查找 gxy 的文件**
[root@VM-20-17-centos ~]# find /var/ -user gxy
/var/spool/mail/gxy
**# 文件是查到了,我如何知道这个文件就是gxy的,可以在命令后加上 -ls,这是 find 自带的参数**
[root@VM-20-17-centos ~]# find /var/ -user gxy -ls
394267 0 -rw-rw---- 1 gxy mail 0 Sep 7 10:39 /var/spool/mail/gxy
2.3.2、-nouser
查找没有属主的文件
**# home 下有三个用户**
[root@VM-20-17-centos home]# ll
total 12
drwx------ 5 gxy gxy 4096 Oct 23 19:02 gxy
drwx------ 2 gy gy 4096 Dec 14 22:10 gy
drwx------ 5 lighthouse lighthouse 4096 Sep 7 10:38 lighthouse
**# 将gy用户删除**
[root@VM-20-17-centos home]# userdel gy
[root@VM-20-17-centos home]# ll
total 12
drwx------ 5 gxy gxy 4096 Oct 23 19:02 gxy
drwx------ 2 1002 1002 4096 Dec 14 22:10 gy
drwx------ 5 lighthouse lighthouse 4096 Sep 7 10:38 lighthouse
**# 删除gy用户,这个时候gy目录下的文件都是没有属主的文件**
[root@VM-20-17-centos home]# find /home -nouser -ls
917506 4 drwx------ 2 1002 1002 4096 Dec 14 22:10 /home/gy
917507 4 -rw-r--r-- 1 1002 1002 231 Apr 1 2020 /home/gy/.bashrc
917508 4 -rw-r--r-- 1 1002 1002 18 Apr 1 2020 /home/gy/.bash_logout
917509 4 -rw-r--r-- 1 1002 1002 193 Apr 1 2020 /home/gy/.bash_profile
2.4、根据文件类型查找
-type TYPE
TYPE可以是以下形式:
**f**: 普通文件
**d**: 目录文件
**l**: 符号链接文件
**s**:套接字文件
**b**: 块设备文件
**c**: 字符设备文件
**p**: 管道文件
例1
搜索文件夹
**# 在当前目录中搜索所有文件夹**
[root@VM-20-17-centos shell]# find -type d
.
./test
./test/test2
./test/test1
如何判断是文件夹呢,需要加 -ls
[root@VM-20-17-centos shell]# find -type d -ls
789256 4 drwxr-xr-x 3 root root 4096 Dec 14 21:13 .
917505 4 drwxr-xr-x 4 root root 4096 Dec 14 21:40 ./test
917566 4 drwxr-xr-x 2 root root 4096 Dec 14 12:51 ./test/test2
917558 4 drwxr-xr-x 2 root root 4096 Dec 11 11:22 ./test/test1
2.5、空文件或目录
# 查看当前目录中的空文件
[root@VM-20-17-centos shell]# find -empty
./test/test1/rc0.d
./test/test1/rc.abc
./test/test1/rc3.d
./test/test1/rc.d
./test/test1/rcabc
./test/test1/rc2.d
./test/test1/rc1.d
# 发现大小都是0字节
[root@VM-20-17-centos shell]# find -empty -ls
917559 0 -rw-r--r-- 1 root root 0 Dec 11 11:22 ./test/test1/rc0.d
917564 0 -rw-r--r-- 1 root root 0 Dec 11 11:22 ./test/test1/rc.abc
917562 0 -rw-r--r-- 1 root root 0 Dec 11 11:22 ./test/test1/rc3.d
917563 0 -rw-r--r-- 1 root root 0 Dec 11 11:22 ./test/test1/rc.d
917565 0 -rw-r--r-- 1 root root 0 Dec 11 11:22 ./test/test1/rcabc
917561 0 -rw-r--r-- 1 root root 0 Dec 11 11:22 ./test/test1/rc2.d
917560 0 -rw-r--r-- 1 root root 0 Dec 11 11:22 ./test/test1/rc1.d
2.6、组合条件
与:-a ,默认多个条件是与关系
或:-o
非:-not !
例1:
查找属于gxy的文件或者是以 .conf结尾的文件
# 或者用 -o 参数,以 .conf 结尾的文件也有可能是其他用户的
[root@VM-20-17-centos home]# find -user gxy -o -name "*.conf"
./gy/c.conf
./gxy
./gxy/d.txt
./gxy/.xterminal
./gxy/.xterminal/last_update
./gxy/.xterminal/version
./gxy/.xterminal/cpu.tmp
# 发现 -ls 只打印了一条,因为find默认是用的and关系,它把第一个 -user gxy 当成一个条件了
,后边 -name 与ls当成一个条件了,因为前面使用or,后边是and,and的优先级高
[root@VM-20-17-centos home]# find -user gxy -o -name "*.conf" -ls
917517 0 -rw-rw-r-- 1 gy gy 0 Dec 15 10:42 ./gy/c.conf
# 可以加括号,类似于分组
[root@VM-20-17-centos home]# find /home \( -user gxy -o -name "*.conf" \) -ls
917517 0 -rw-rw-r-- 1 gy gy 0 Dec 15 10:42 /home/gy/c.conf
656302 4 drwx------ 5 gxy gxy 4096 Dec 15 10:43 /home/gxy
671711 0 -rw-rw-r-- 1 gxy gxy 0 Dec 15 10:43 /home/gxy/d.txt
786447 4 drwxrwxr-x 3 gxy gxy 4096 Oct 26 10:02 /home/gxy/.xterminal
德·摩根定律:
(非 A) 或 (非 B) = 非(A 且 B)
(非 A) 且 (非 B) = 非(A 或 B)
(非 A) 或 (非 B) = 非(A 且 B)
A=黄色,B=绿色
(非 A) 或 (非 B)
非A就是不是黄色,也就是2、4
非B就是不是绿色,也就是1、2
(非 A) 或 (非 B)=2、4或者1、4=1、2、4
非(A 且 B)
A且B=3
非(A 且 B)=非3=1、2、4
例2:
# (非 A) 且 (非 B) = 非(A 或 B)
[root@VM-20-17-centos home]# find /etc/ ! -type d -o ! -empty |wc -l
2902
[root@VM-20-17-centos home]# find /etc/ ! \( -type d -a -empty \) |wc -l
2902
2.7、排除目录 -prune
在etc目录下找除了 /etc/security 目下其他目录下以 .conf 结尾的文件
注意:排除 /etc/security 目录一定不要写成 /etc/security/ ,写成这种是仍然找到security目录下文件的,所以一定要注意!!!
**# 如果过滤 /etc/security 目录写成 /etc/security/ 结果如下:**
[root@VM-20-17-centos ~]# find /etc -path '/etc/security/' -a -prune -o -name "*.conf" | grep security | grep
**# 还是会列出来 /etc/security 中的文件的**
[root@VM-20-17-centos ~]# find /etc -path '/etc/security/' -a -prune -o -name "*.conf" | grep security | grep security
find: warning: -path /etc/security/ will not match anything because it ends with /.
/etc/security/chroot.conf
/etc/security/pwquality.conf
/etc/security/namespace.conf
/etc/security/access.conf
/etc/security/group.conf
/etc/security/sepermit.conf
/etc/security/pam_env.conf
/etc/security/limits.d/20-nproc.conf
/etc/security/limits.conf
/etc/security/faillock.conf
/etc/security/time.conf
/etc/fail2ban/filter.d/apache-modsecurity.conf
**# 写成/etc/security 会把该目录列出来,但不会列出该目录下的文件**
[root@VM-20-17-centos ~]# find /etc -path '/etc/security' -a -prune -o -name "*.conf" | grep security
/etc/security
/etc/fail2ban/filter.d/apache-modsecurity.conf
**# 正确的写法如下:**
[root@VM-20-17-centos ~]# find /etc -path '/etc/security' -a -prune -o -name "*.conf"#
-path '/etc/security'
匹配的是路径 /etc/security
,它指的是这个精确路径,不包括子目录。
-path '/etc/security/'
指的是 /etc/security/
目录,结尾有一个斜杠,意味着这个路径指的是该目录及其子目录。
2.8、根据文件大小来查找
**-size ****[+|-]#UNIT #常用单位:k, M, G,c(byte),注意大小写敏感****
#UNIT: ****#表示(#-1, #],如:6k 表示(5k,6k]****
-#UNIT ****#表示[0,#-1],如:-6k 表示[0,5k]****
+#UNIT ****#表示(#,∞),如:+6k 表示(6k,∞)**
2.8.1、-size
# 构建三个空文件,1.txt大小为1M,2.txt大小为2M,3.txt大小不到2M
[root@VM-20-17-centos test3]# dd if=/dev/zero of=1.txt bs=1k count=1024
[root@VM-20-17-centos test3]# dd if=/dev/zero of=2.txt bs=1k count=2048
[root@VM-20-17-centos test3]# dd if=/dev/zero of=3.txt bs=1k count=2040
[root@VM-20-17-centos test3]# ll -h
total 5.0M
-rw-r--r-- 1 root root 1.0M Dec 15 13:24 1.txt
-rw-r--r-- 1 root root 2.0M Dec 15 13:24 2.txt
-rw-r--r-- 1 root root 2.0M Dec 15 13:25 3.txt
按照大小查找文件
# 按照2M的大小查发现3.txt也是符合要求,这个搜索比较怪,因为这个搜的是2M到2M-1区间的
所有文件,也就是1M-2M,不包含1M,但包含2M,3.txt不到2M也是符合要求的
[root@VM-20-17-centos test3]# find -size 2M
./3.txt
./2.txt
# 按照2048k查找就是2048k到2048k-1 ,也就是2047k,没有2047k,就还只能匹配2048k一个文件
[root@VM-20-17-centos test3]# find -size 2048k
./2.txt
例1
按照大小查找文件
**# 按照2M的大小查发现3.txt也是符合要求,这个搜索比较怪,因为这个搜的是2M到2M-1区间的
所有文件,也就是1M-2M,不包含1M,但包含2M,3.txt不到2M也是符合要求的**
[root@VM-20-17-centos test3]# find -size 2M
./3.txt
./2.txt
**# 按照2048k查找就是2048k到2048k-1 ,也就是2047k,没有2047k,就还只能匹配2048k一个文件**
[root@VM-20-17-centos test3]# find -size 2048k
./2.txt
例2
**-size 6k是5k到6k,不包含5k,包含6k,(5k,6k]
-size -6k是0k到5k,包含5k,[0,5k]
-size +6k是大于6k(6k,∞)**
# -2048k相当于0k-2047k,1.txt是1M,也就是1024k,3.txt是2040k,小于2047k,符合要求
[root@VM-20-17-centos test3]# find -size -2048k
.
./3.txt
./1.txt
# **-size +6k是大于1024k(1024k,∞),,1.txt是1024k不符合要求,2.txt、3.txt均符合要求**
[root@VM-20-17-centos test3]# find -size +1024k
./3.txt
./2.txt
2.9、根据文件大小来查找
**atime**
定义:atime 记录的是文件的最后一次访问时间,即文件内容被读取时的时间。
操作:当文件被读取或执行时(例如,cat file 或 less file),atime 会更新。
更新方式:atime 在文件读取操作时更新,但如果文件内容被修改(如写入数据),atime 不会更新,只有在文件访问(而非写入)时,才会更新。
# 以“天”为单位
-atime [+|-]#
# #表示[#,#+1),**如:-atime 10 表示10天到第11天[10,11)**
+# #表示[#+1,∞],**如:-atime +10 表示11天到11天以上[11,11天以上]**
-# #表示[0,#),**如:-atime -10 表示10天以内,不包含10天,[0,10)
mtime
定义:mtime 记录的是文件内容的最后一次修改时间。
操作:当文件的内容被修改时,mtime 会更新。例如,使用 echo "text" > file 命令向文件写入
内容时,mtime 会更新。**
更新方式:mtime 会在文件内容改变时更新(例如写入数据,或者重定向内容到文件),但它不会在文件被访问时更新(例如只读取文件时)。
**ctime
定义:ctime 记录的是文件的元数据(如文件权限、所有者、文件名、硬链接等)发生变化的时间,而不仅仅是文件内容的变化。
操作:当文件的权限、所有者、组、文件名或其他元数据发生变化时,ctime 会更新。但 文件内容的修改(如写入数据)并不会直接更新 ctime,ctime 只在文件的元数据发生改变时更新。
更新方式:例如,当你改变文件的权限、改变文件的所有者,或修改文件的硬链接时,ctime 会更新。**
#以“分钟”为单位
-amin
-mmin
-cmin
2.10、根据权限查找
-perm [/|-]MODE
MODE: 精确权限匹配
/MODE:任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+ 从CentOS 7开始淘汰
-MODE:每一类对象都必须同时拥有指定权限,与关系
0 表示不关注
例1
精确查找特定权限的文件 MODE
[root@VM-20-17-centos test3]# ll
total 5112
-rw-r--r-- 1 root root 1048576 Dec 15 13:24 1.txt
-rw-r--r-- 1 root root 2097152 Dec 15 13:24 2.txt
-rw-r--r-- 1 root root 2088960 Dec 15 13:25 3.txt
**# 修改权限**
[root@VM-20-17-centos test3]# chmod 600 1.txt
[root@VM-20-17-centos test3]# chmod 444 2.txt
**# 查看444权限的文件**
[root@VM-20-17-centos test3]# find -perm 444 -ls
917521 2048 -r--r--r-- 1 root root 2097152 Dec 15 13:24 ./2.txt
例2
属主、属组、其他只有一个有权限既可匹配 /MODE
# /444 代表不管是属主、属组、其他只有一个有 4 权限的就能匹配成功
[root@VM-20-17-centos test3]# find -perm /444 -ls
917519 4 drwxr-xr-x 2 root root 4096 Dec 15 13:25 .
917522 2040 -rw-r--r-- 1 root root 2088960 Dec 15 13:25 ./3.txt
917520 1024 -rw------- 1 root root 1048576 Dec 15 13:24 ./1.txt
917521 2048 -r--r--r-- 1 root root 2097152 Dec 15 13:24 ./2.txt
例3
600中的0代表不关心,/600 就代表着不关心所属组和其他组的权限,6代表是 r 和 w 两个权限,只关心属主的权限,r 和 w 是或者的关系,就是属主有 r 或者 w 都可以匹配,当然rw也是可以匹配的。
[root@VM-20-17-centos test3]# find -perm /600 -ls
917519 4 drwxr-xr-x 2 root root 4096 Dec 15 13:25 .
917522 2040 -rw-r--r-- 1 root root 2088960 Dec 15 13:25 ./3.txt
917520 1024 -rw------- 1 root root 1048576 Dec 15 13:24 ./1.txt
917521 2048 -r--r--r-- 1 root root 2097152 Dec 15 13:24 ./2.txt
例4
属主、属组、其他都必须有4的权限,这个文件只要符合要求其他的不管还有什么权限
# **属主、属组、其他都必须有读的权限,不管该文件是否还有其他权限,只要符合要求就打印**
[root@VM-20-17-centos test3]# find -perm -444 -ls
917519 4 drwxr-xr-x 2 root root 4096 Dec 15 13:25 .
917522 2040 -rw-r--r-- 1 root root 2088960 Dec 15 13:25 ./3.txt
917521 2048 -r--r--r-- 1 root root 2097152 Dec 15 13:24 ./2.txt
例5
-600,只关心属主,但是是and的关系,就是属主既要有 r 权限,又要有 w 权限,二者需同时满足。
[root@VM-20-17-centos test3]# find -perm -600 -ls
917519 4 drwxr-xr-x 2 root root 4096 Dec 15 13:25 .
917522 2040 -rw-r--r-- 1 root root 2088960 Dec 15 13:25 ./3.txt
917520 1024 -rw------- 1 root root 1048576 Dec 15 13:24 ./1.txt
2.11、处理动作
-print:默认的处理动作,显示至屏幕
-ls:类似于对查找到的文件执行"ls -dils"命令格式输出
-fls file:查找到的所有文件的长格式信息保存至指定文件中,相当于 -ls > file
-delete:删除查找到的文件,慎用!
-ok COMMAND {} \; 对查找到的每个文件执行由COMMAND指定的命令,对于每个文件执行命令之前,都会
交互式要求用户确认
-exec COMMAND {} \; 对查找到的每个文件执行由COMMAND指定的命令
{}: 用于引用查找到的文件名称自身
2.11.1、-print
我们查找文件的时候默认是省略了 -print 可以不写,效果一样,如下
[root@VM-20-17-centos shell]# find |wc -l
33
[root@VM-20-17-centos shell]# find -print |wc -l
33
2.11.2、 -fls file
将文件名输入到指定的文件中
[root@VM-20-17-centos shell]# find -name '*.txt' -fls test.log
[root@VM-20-17-centos shell]# cat !$
cat test.log
917522 2040 -rw-r--r-- 1 root root 2088960 Dec 15 13:25 ./test/test3/3.txt
917520 1024 -rw------- 1 root root 1048576 Dec 15 13:24 ./test/test3/1.txt
917521 2048 -r--r--r-- 1 root root 2097152 Dec 15 13:24 ./test/test3/2.txt
917573 4 -rw-r--r-- 1 root root 14 Dec 11 23:30 ./test/test2/e.txt
917567 4 -rw-r--r-- 1 root root 22 Dec 11 23:17 ./test/test2/d.txt
917568 4 -rw-r--r-- 1 root root 9 Dec 11 23:06 ./test/test2/b.txt
917570 4 -rw-r--r-- 1 root root 9 Dec 11 23:06 ./test/test2/a.txt
917569 4 -rw-r--r-- 1 root root 45 Dec 11 23:14 ./test/test2/c.txt
# 其他写法,效果是一样的,只是不用 -fls 了
[root@VM-20-17-centos shell]# find -name '*.txt' -ls > test.log
[root@VM-20-17-centos shell]# cat !$
cat test.log
917522 2040 -rw-r--r-- 1 root root 2088960 Dec 15 13:25 ./test/test3/3.txt
917520 1024 -rw------- 1 root root 1048576 Dec 15 13:24 ./test/test3/1.txt
917521 2048 -r--r--r-- 1 root root 2097152 Dec 15 13:24 ./test/test3/2.txt
917573 4 -rw-r--r-- 1 root root 14 Dec 11 23:30 ./test/test2/e.txt
917567 4 -rw-r--r-- 1 root root 22 Dec 11 23:17 ./test/test2/d.txt
917568 4 -rw-r--r-- 1 root root 9 Dec 11 23:06 ./test/test2/b.txt
917570 4 -rw-r--r-- 1 root root 9 Dec 11 23:06 ./test/test2/a.txt
917569 4 -rw-r--r-- 1 root root 45 Dec 11 23:14 ./test/test2/c.txt
2.11.3、-delete
删除查找到的文件,属于高危命令,很危险,不建议使用
[root@VM-20-17-centos shell]# find -name 'a.txt' -delete
[root@VM-20-17-centos shell]# find -name '*.txt'
./test/test3/3.txt
./test/test3/1.txt
./test/test3/2.txt
./test/test2/e.txt
./test/test2/d.txt
./test/test2/b.txt
./test/test2/c.txt
2.11.4、-ok COMMAND {} ;
将find找到的文件执行一个动作,如cp或者mv等,find搜到的命令都保存在 {} 中,命令结束需要用 ; ,这是固定写法。只不过每对一个文件执行动作都需要确认,如果确认就输入 y ,不想对某个文件执行动作直接回车即可。缺点很明显,就是操作每个文件都需要确认,如果文件太多就不太适合了,这个时候就可以用到 -exec 参数了,参考2.11.5部分。
[root@VM-20-17-centos test3]# ll
total 5112
-rw------- 1 root root 1048576 Dec 15 13:24 1.txt
-r--r--r-- 1 root root 2097152 Dec 15 13:24 2.txt
-rw-r--r-- 1 root root 2088960 Dec 15 13:25 3.txt
**# 这里拷贝3.txt、1.txt是同意的,就直接输入y,但是2.txt不行拷贝了,就直接回车**
[root@VM-20-17-centos test3]# find -name "*.txt" -ok cp {} /opt \;
< cp ... ./3.txt > ? y
< cp ... ./1.txt > ? y
< cp ... ./2.txt > ?
**# 因为2.txt是不想拷贝的,直接回车了,所以这里就没有2.txt的文件**
[root@VM-20-17-centos test3]# ll /opt
total 7740
-rw------- 1 root root 1048576 Dec 16 10:19 1.txt
-rw-r--r-- 1 root root 2088960 Dec 16 10:19 3.txt
2.11.5、-exec COMMAND {} ;
与2.11.4中ok的用法一样,只不过 -exec 是非交互式的,对每个文件操作不用再确认了,直接对find查到的文件操作。
例1
[root@VM-20-17-centos test3]# touch {a..c}.conf
[root@VM-20-17-centos test3]# find -name "*.conf" -exec cp {} /opt \;
[root@VM-20-17-centos test3]# **ll /opt**
total 7740
-rw------- 1 root root 1048576 Dec 16 10:19 1.txt
-rw-r--r-- 1 root root 2088960 Dec 16 10:19 3.txt
-rw-r--r-- 1 root root 0 Dec 16 10:31 a.conf
-rw-r--r-- 1 root root 0 Dec 16 10:31 b.conf
-rw-r--r-- 1 root root 0 Dec 16 10:31 c.conf
例2
找到大于100M的文件,将其删除
**# 先创建3个文件,分别是80M,120M,150M**
[root@VM-20-17-centos test3]# dd if=/dev/zero of=test1.log bs=1M count=80
**# 删除大于100M的文件**
[root@VM-20-17-centos test3]# find -size +100M -exec rm -rf {} \;
**# 查看目录已经没有大于100M的文件了**
[root@VM-20-17-centos test3]# ll -h
total 85M
-rw------- 1 root root 1.0M Dec 15 13:24 1.txt
-r--r--r-- 1 root root 2.0M Dec 15 13:24 2.txt
-rw-r--r-- 1 root root 2.0M Dec 15 13:25 3.txt
-rw-r--r-- 1 root root 0 Dec 16 10:31 a.conf
-rw-r--r-- 1 root root 0 Dec 16 10:31 b.conf
-rw-r--r-- 1 root root 0 Dec 16 10:31 c.conf
-rw-r--r-- 1 root root 80M Dec 16 10:50 test1.log
例3
删除大于80M,小于100M的日志
[root@VM-20-17-centos test3]# ll -h *.log
-rw-r--r-- 1 root root 80M Dec 16 10:50 test1.log
-rw-r--r-- 1 root root 90M Dec 16 10:56 test2.log
-rw-r--r-- 1 root root 100M Dec 16 10:56 test3.log
**# 查看大于80M,小于100M的日志**
[root@VM-20-17-centos test3]# find -size +80M -size -100M -exec ls -lh {} \;
-rw-r--r-- 1 root root 90M Dec 16 10:56 ./test2.log
**# 删除大于80M,小于100M的日志**
[root@VM-20-17-centos test3]# find -size +80M -size -100M -delete
**# 符合要求的文件已被删除**
[root@VM-20-17-centos test3]# ll -h
total 185M
-rw------- 1 root root 1.0M Dec 15 13:24 1.txt
-r--r--r-- 1 root root 2.0M Dec 15 13:24 2.txt
-rw-r--r-- 1 root root 2.0M Dec 15 13:25 3.txt
-rw-r--r-- 1 root root 0 Dec 16 10:31 a.conf
-rw-r--r-- 1 root root 0 Dec 16 10:31 b.conf
-rw-r--r-- 1 root root 0 Dec 16 10:31 c.conf
-rw-r--r-- 1 root root 80M Dec 16 10:50 test1.log
-rw-r--r-- 1 root root 100M Dec 16 10:56 test3.log
**# 第二种写法**
[root@VM-20-17-centos test3]# find -size +80M -size -100M -exec rm -rf {} \;
2.12、参数替换 xargs
**由于很多命令不支持管道|来传递参数,**xargs用于产生某个命令的参数,xargs 可以读入 stdin 的数据,并且以空格符或回车符将 stdin 的数据分隔成为参数。
优点:参数可以动态生成。
另外,许多命令不能接受过多参数,命令执行可能会失败,xargs 可以解决。
注意:文件名或者是其他意义的名词内含有空格符的情况。
find 经常和 xargs 命令进行组合,形式如下:
find | xargs COMMAND
xargs可以接收传参
xargs cmd 参数(动态生成的参数)
xargs 接收输入 作为cmd的参数
例1
**# echo 的输入将传给xargs作为ls -l参数**
[root@VM-20-17-centos test3]# echo 1.txt |xargs ls -l
-rw------- 1 root root 1048576 Dec 15 13:24 1.txt
[root@VM-20-17-centos ~]# seq 10 |xargs
1 2 3 4 5 6 7 8 9 10
# 与上一条命令相比相当于隐藏了个echo,可以省略
[root@VM-20-17-centos ~]# seq 10 |xargs echo
1 2 3 4 5 6 7 8 9 10
# 其实seq是一个数字一行
[root@VM-20-17-centos ~]# seq 10
1
2
3
4
5
6
7
8
9
10
**# 想让一个数字一行可以加参数 -n 后边跟数字,数字代表着几个数字一行**
[root@VM-20-17-centos ~]# seq 10 |xargs -n1
1
2
3
4
5
6
7
8
9
10
[root@VM-20-17-centos ~]# seq 10 |xargs -n2
1 2
3 4
5 6
7 8
9 10
[root@VM-20-17-centos ~]# seq 10 |xargs -n3
1 2 3
4 5 6
7 8 9
10
例2
如果想一下子创建10个用户,又不想一个一个命令去输入
[root@VM-20-17-centos ~]# echo user{1..10}
user1 user2 user3 user4 user5 user6 user7 user8 user9 user10
[root@VM-20-17-centos ~]# echo user{1..10} |xargs -n1
user1
user2
user3
user4
user5
user6
user7
user8
user9
user10
**# 批量创建10个用户**
[root@VM-20-17-centos ~]# echo user{1..10} |xargs -n1 useradd
[root@VM-20-17-centos ~]# getent passwd
......
gxy:x:1001:1001::/home/gxy:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
ngin:x:995:992::/home/ngin:/sbin/nologin
nginx:x:994:991::/home/nginx:/sbin/nologin
gy:x:1002:1002::/home/gy:/bin/bash
user1:x:1003:1003::/home/user1:/bin/bash
user2:x:1004:1004::/home/user2:/bin/bash
user3:x:1005:1005::/home/user3:/bin/bash
user4:x:1006:1006::/home/user4:/bin/bash
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1008::/home/user6:/bin/bash
user7:x:1009:1009::/home/user7:/bin/bash
user8:x:1010:1010::/home/user8:/bin/bash
user9:x:1011:1011::/home/user9:/bin/bash
user10:x:1012:1012::/home/user10:/bin/bash
删除刚创建的10个用户
[root@VM-20-17-centos ~]# echo user{1..10} |xargs -n1 userdel -r
**# 查看已经没有了**
[root@VM-20-17-centos ~]# getent passwd
例3
创建文件将/boot目录下的inode占满
**# 查看当前的inode使用情况**
[root@calm-box-1 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 120171 339 119832 1% /dev
tmpfs 124775 1 124774 1% /dev/shm
tmpfs 819200 535 818665 1% /run
/dev/sda2 1248000 80898 1167102 7% /
/dev/sda1 524288 308 523908 1% /boot
tmpfs 24955 16 24939 1% /run/user/0
**# 直接创建文件**
[root@calm-box-1 ~]# touch /boot/file{1..524288}
-bash: /usr/bin/touch: Argument list too long
**# 直接使用xargs传参创建,这次不报错了,-n10000,就是一次建10000个**
[root@calm-box-1 ~]# echo /boot/file{1..524288} |xargs -n10000 touch
**# 查看创建后的文件,用ls都无法查看了**
[root@calm-box-1 ~]# ls /boot/file*
-bash: /usr/bin/ls: Argument list too long
**# 如何查看呢,我们可以用刚才的方法进行查看,-n1一个一个查看**
[root@calm-box-1 ~]# echo /boot/file* |xargs -n1 ls
**# 删除刚创建的文件,可以1万1万的删**
[root@calm-box-1 ~]# echo /boot/file* |xargs -n10000 rm
**# 再次查看已经降下来了**
[root@calm-box-1 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 120171 339 119832 1% /dev
tmpfs 124775 1 124774 1% /dev/shm
tmpfs 819200 535 818665 1% /run
/dev/sda2 1248000 80898 1167102 7% /
/dev/sda1 524288 308 523908 1% /boot
tmpfs 24955 16 24939 1% /run/user/0
例4
批量下载bilibli的资源
**# 并发下载bilibli视频**
yum install python3-pip -y
pip3 install you-get
**# -i 代表前边的60,-P3 就代表并行启3个下载任务**
seq 60 |xargs -i -P3 you-get https://www.bilibli.com/video/BV14K411W7UF?p={}
例5
特殊情况
传到xargs的内容,xargs默认是以空白符作为分隔符的,但是在实际使用时有可能会出现一个现象就是文件名里边有空白符,如下:
# 创建特殊的文件
[root@calm-box-1 ~]# touch 'a b'
[root@calm-box-1 ~]# touch 'c d'
[root@calm-box-1 ~]# ll
total 2651996
-rw-r--r-- 1 root root 0 Dec 16 10:06 'a b'
-rw------- 1 root root 2476990976 Nov 12 02:00 awvs.tar.gz
-rw-r--r-- 1 root root 0 Dec 16 10:06 'c d'
-rw------- 1 root root 10928640 Oct 11 04:37 flannel-cni-plugin.tar.gz
-rw------- 1 root root 83911680 Oct 11 04:36 flannel-v0257.tar.gz
drwxr-xr-x 3 root root 4096 Sep 29 15:53 install_docker
-rw-rw-r-- 1 root root 143783695 Jun 2 2024 install_docker.0629.tar.gz
-rw-r--r-- 1 root root 197 Sep 29 15:01 virt-sysprep-firstboot.log
用find查看
[root@calm-box-1 ~]# find -type f
./flannel-cni-plugin.tar.gz
**./a b**
./.bash_profile
./.bash_logout
./virt-sysprep-firstboot.log
./install_docker.0629.tar.gz
./.bash_history
./.tcshrc
./.lesshst
./.bashrc
./flannel-v0257.tar.gz
./.cshrc
./install_docker/docker/docker-proxy
./install_docker/docker/docker
./install_docker/docker/dockerd
./install_docker/docker/runc
./install_docker/docker/ctr
./install_docker/docker/containerd
./install_docker/docker/containerd-shim-runc-v2
./install_docker/docker/containerd-shim
./install_docker/docker/docker-init
./install_docker/daemon.json
./install_docker/docker.service
./install_docker/docker-20.10.12.tgz
./install_docker/install_docker.sh
./install_docker/docker-compose-Linux-x86_64
./awvs.tar.gz
**./c d**
./.ssh/authorized_keys
查看发现特殊文件找不到了,因为xargs默认是以空白符作为分隔符的,’a b’,’c d’中间都有空白符,所以它认为a是一个文件,b是一个文件,c和d也是单独的两个文件,所以就找不到了
[root@calm-box-1 ~]# find -type f |xargs ls -l
ls: cannot access './a': No such file or directory
ls: cannot access 'b': No such file or directory
ls: cannot access './c': No such file or directory
ls: cannot access 'd': No such file or directory
-rw------- 1 root root 2476990976 Nov 12 02:00 ./awvs.tar.gz
-rw------- 1 root root 2401 Nov 12 02:50 ./.bash_history
-rw-r--r--. 1 root root 18 May 11 2022 ./.bash_logout
-rw-r--r--. 1 root root 141 May 11 2022 ./.bash_profile
-rw-r--r--. 1 root root 429 May 11 2022 ./.bashrc
为了解决这个问题,可以把分隔符改了,不让以空格作为分隔符了,以ascii码中的0作为分隔符,就是ascii码中的第一个,也就是NUL,ascii中的0是不可能作为文件名的,有两个符号不能作为文件名,一个NUL,一个是斜线
[root@VM-20-17-centos ~]# ascii
Usage: ascii [-adxohv] [-t] [char-alias...]
-t = one-line output -a = vertical format
-d = decimal table -o = octal table -x = hex table -b binary table
-h = this help screen -v = version information
Prints all aliases of an ASCII character. Args may be chars, C \-escapes,
English names, ^-escapes, ASCII mnemonics, or numerics in decimal/octal/hex.
Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex
0 00 NUL 16 10 DLE 32 20 48 30 0 64 40 @ 80 50 P 96 60 ` 112 70 p
1 01 SOH 17 11 DC1 33 21 ! 49 31 1 65 41 A 81 51 Q 97 61 a 113 71 q
2 02 STX 18 12 DC2 34 22 " 50 32 2 66 42 B 82 52 R 98 62 b 114 72 r
3 03 ETX 19 13 DC3 35 23 # 51 33 3 67 43 C 83 53 S 99 63 c 115 73 s
4 04 EOT 20 14 DC4 36 24 $ 52 34 4 68 44 D 84 54 T 100 64 d 116 74 t
5 05 ENQ 21 15 NAK 37 25 % 53 35 5 69 45 E 85 55 U 101 65 e 117 75 u
6 06 ACK 22 16 SYN 38 26 & 54 36 6 70 46 F 86 56 V 102 66 f 118 76 v
7 07 BEL 23 17 ETB 39 27 ' 55 37 7 71 47 G 87 57 W 103 67 g 119 77 w
8 08 BS 24 18 CAN 40 28 ( 56 38 8 72 48 H 88 58 X 104 68 h 120 78 x
9 09 HT 25 19 EM 41 29 ) 57 39 9 73 49 I 89 59 Y 105 69 i 121 79 y
10 0A LF 26 1A SUB 42 2A * 58 3A : 74 4A J 90 5A Z 106 6A j 122 7A z
11 0B VT 27 1B ESC 43 2B + 59 3B ; 75 4B K 91 5B [ 107 6B k 123 7B {
12 0C FF 28 1C FS 44 2C , 60 3C < 76 4C L 92 5C \ 108 6C l 124 7C |
13 0D CR 29 1D GS 45 2D - 61 3D = 77 4D M 93 5D ] 109 6D m 125 7D }
14 0E SO 30 1E RS 46 2E . 62 3E > 78 4E N 94 5E ^ 110 6E n 126 7E ~
15 0F SI 31 1F US 47 2F / 63 3F ? 79 4F O 95 5F _ 111 6F o 127 7F DEL
用特殊符合作为分隔符查看文件就可以看到了
# 这样就可以正常显示了
[root@calm-box-1 ~]# find -type f -print0 |xargs -0 ls -l
-rw-r--r-- 1 root root 0 Dec 16 10:06 './a b'
-rw------- 1 root root 2476990976 Nov 12 02:00 ./awvs.tar.gz
-rw------- 1 root root 2401 Nov 12 02:50 ./.bash_history
-rw-r--r--. 1 root root 18 May 11 2022 ./.bash_logout
-rw-r--r--. 1 root root 141 May 11 2022 ./.bash_profile
-rw-r--r--. 1 root root 429 May 11 2022 ./.bashrc
-rw-r--r-- 1 root root 0 Dec 16 10:06 './c d'
-rw-r--r--. 1 root root 100 May 11 2022 ./.cshrc
-rw------- 1 root root 10928640 Oct 11 04:37 ./flannel-cni-plugin.tar.gz
-rw------- 1 root root 83911680 Oct 11 04:36 ./flannel-v0257.tar.gz
......