6 文件查找
使用locate命令:
- 非实时查找(数据库查找)
使用find命令
- 实时查找
压缩和解压缩工具
6.1 locate命令
查询系统上预建的文件索引数据库:
/var/lib/mlocate/mlocate.db
依赖于事先构建的索引
索引的构建是在系统较为空闲时自动进行(周期性任务),管理员手动更新数据库:
updatedb
索引构建过程需要遍历整个根文件系统,极消耗资源
工作特点:
- 查找速度快
- 模糊查找
- 非实时查找
- 搜索的是文件的全路径,不仅仅是文件名
- 可能只搜索用户具备读取和执行权限的目录
语法:
locate KEYWORD
- -i 不区分大小写的搜索
- -n N 只列举前N个匹配项目
- -r 使用正则表达式
示例
[root@centos-full ~]# locate passwd
locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
[root@centos-full ~]# updatedb
[root@centos-full ~]# locate passwd
/etc/passwd
/etc/passwd-
/etc/pam.d/passwd
/etc/security/opasswd
...
搜索名称或路径中带有“conf”的文件:
locate conf
使用Regex来搜索以“.conf”结尾的文件:
locate -r ‘\.conf$’
范例: locatedb创建数据库
[root@centos8 ~]#dnf -y install mlocate
[root@centos8 ~]#locate conf
locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
[root@centos8 ~]#updatedb
[root@centos8 ~]#ll /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 1041065 Jun 11 20:08 /var/lib/mlocate/mlocate.db
[root@centos8 ~]#locate -n 3 conf
/boot/config-4.18.0-147.el8.x86_64
/boot/grub2/i386-pc/configfile.mod
/boot/loader/entries/5b85fc7444b240a992c42ce2a9f65db5-0-rescue.conf
范例: 文件新创建和删除,无法马上更新locate数据库
[root@centos8 ~]#touch test.log
[root@centos8 ~]#locate test.log
locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
[root@centos8 ~]#updatedb
[root@centos8 ~]#locate test.log
/root/test.log
[root@centos8 ~]#touch test2.log
[root@centos8 ~]#locate test2.log
[root@centos8 ~]#updatedb
[root@centos8 ~]#locate test2.log
/root/test2.log
[root@centos8 ~]#rm -f test2.log
[root@centos8 ~]#locate test2.log
/root/test2.log
[root@centos8 ~]#
范例:
[root@centos8 ~]#locate -n 10 -ir '\.CONF$'
/boot/loader/entries/5b85fc7444b240a992c42ce2a9f65db5-0-rescue.conf
/boot/loader/entries/5b85fc7444b240a992c42ce2a9f65db5-4.18.0-147.el8.x86_64.conf
/etc/autofs.conf
/etc/autofs_ldap_auth.conf
/etc/dracut.conf
/etc/fuse.conf
/etc/host.conf
/etc/idmapd.conf
/etc/kdump.conf
/etc/krb5.conf
6.2 find命令
实时查找工具,通过遍历指定路径完成文件查找
工作特点:
- 查找速度略慢
- 精确 查找
- 实时查找
- 可能只搜索用户具备读取和执行权限的目录
语法:
find [OPTION]... [查找路径] [查找条件] [处理动作]
- 查找路径:指定具体目标路径;默认为当前目录
- 查找条件:指定的查找标准,可以文件名、大小、类型、权限等标准进行;
- 默认为找出指定路径下的所有文件
- 处理动作:对符合条件的文件做操作,默认输出至屏幕
6.2.1 查找条件
6.2.1.1 指搜索层级
-
-maxdepth # 最大搜索目录深度,指定目录为第1级
-
-mindepth # 最小搜索目录深度
-
-depth 先处理目录内的文件,再处理目录
示例:搜索范围为第二层目录
find /etc -maxdepth 2 -mindepth 2
6.2.1.2 根据文件名和inode查找
- -name “文件名称”:支持使用通配符
- *, ?, [], [^]
- -iname “文件名称”:不区分字母大小写
- -inum n 按inode号查找
- -samefile name 相同inode号的文件
- -links n 链接数为n的文件
- -regex “PATTERN”:以PATTERN匹配整个文件路径,而非文件名称
范例:
[root@centos-full data]# find /data -maxdepth 2 -mindepth
[root@centos-full data]# find /data -iname yum
/data/yum
/data/logrotate.d/yum
[root@centos-full data]# ll -i yum
total 20
3530 drwxr-xr-x. 2 root root 4096 Nov 5 2018 fssnap.d
3533 drwxr-xr-x. 2 root root 4096 Jun 9 21:22 pluginconf.d
3531 drwxr-xr-x. 2 root root 4096 Jun 9 21:20 protected.d
3526 drwxr-xr-x. 2 root root 4096 Jun 9 21:23 vars
3529 -rw-r--r--. 1 root root 444 Nov 5 2018 version-groups.conf
[root@centos-full data]# find /data -inum 3529
/data/yum/version-groups.conf
[root@centos-full data]# ln /data/yum/version-groups.conf /data/yum/version-groups.conf.bak
[root@centos-full data]# find /data -samefile /data/yum/version-groups.conf
/data/yum/version-groups.conf
/data/yum/version-groups.conf.bak
/data/version-groups.conf
[root@centos-full data]# find -regex '.*\.sh$'
./X11/xinit/xinitrc.d/localuser.sh
./X11/xinit/xinitrc.d/50-xinput.sh
......
范例:
find -name snow.png
find -iname snow.png
find / -name ".txt"
find /var –name "log*"
[root@centos8 data]#find -regex ".*\.txt$"
./scripts/b.txt
./f1.txt
6.2.1.3 根据属主、属组查找
- -user USERNAME:查找属主为指定用户(UID)的文件
- -group GRPNAME: 查找属组为指定组(GID)的文件
- -uid UserID:查找属主为指定的UID号的文件
- -gid GroupID:查找属组为指定的GID号的文件
- -nouser:查找没有属主的文件
- -nogroup:查找没有属组的文件
范例:
[root@centos-full data]# useradd user1
[root@centos-full data]# chmod a+w /data
[root@centos-full data]# su user1
[user1@centos-full data]$ touch user1.tst
[user1@centos-full data]$ exit
exit
[root@centos-full data]# ll ./user1.tst
-rw-rw-r--. 1 user1 user1 0 Jun 10 20:23 ./user1.tst
[root@centos-full data]# userdel user1
[root@centos-full data]# ll ./user1.tst
-rw-rw-r--. 1 1001 1001 0 Jun 10 20:23 ./user1.tst
[root@centos-full data]# find /data -nouser
/data/user1.tst
[root@centos-full data]# find /data -nogroup
/data/user1.tst
[root@centos-full data]# chown cc1 user1.tst
[root@centos-full data]# ll ./user1.tst
-rw-rw-r--. 1 cc1 1001 0 Jun 10 20:23 ./user1.tst
[root@centos-full data]# find /data -nouser
[root@centos-full data]# find /data -nogroup
/data/user1.tst
6.2.1.4 根据文件类型查找
- -type TYPE:
- f: 普通文件
- d: 目录文件
- l: 符号链接文件
- s:套接字文件
- b: 块设备文件
- c: 字符设备文件
- p: 管道文件
范例:
#查看/home的目录
find /home –type d -ls
6.2.1.5 空文件或目录
- -empty : 查找空文件或空目录
示例:
find /data -empty
find /data -tpye d -empty
6.2.1.6 组合条件
- 与:-a 多个条件时默认为-a 可省略
- 或:-o
- 非:-not, !
范例:
[root@centos-full data]# find /data -name "u*" -user cc1 -ls
3545 0 -rw-rw-r-- 1 cc1 1001 0 Jun 10 20:23 /data/user1.tst
[root@centos-full data]# find /data -name "u???" -o -user cc1
/data/udev
/data/systemd/user
/data/dconf/profile/user
/data/user1.tst
/data/xdg/systemd/user
/data/selinux/targeted/active/modules/100/udev
/data/selinux/targeted/active/modules/100/uucp
注:上例中, -o用法后如果加-ls 需加括号,
[root@centos-full data]# find /data -name "u???" -o -user cc1 -ls
3545 0 -rw-rw-r-- 1 cc1 1001 0 Jun 10 20:23 /data/user1.tst
###以上-ls只是针对 -o后面的命令
[root@centos-full data]# find /data \( -name "u???" -o -user cc1 \) -ls
3377 4 drwxr-xr-x 3 root root 4096 Jun 9 21:29 /data/udev
3262 4 drwxr-xr-x 2 root root 4096 Oct 31 2018 /data/systemd/user
563 4 -rw-r--r-- 1 root root 61 Nov 2 2018 /data/dconf/profile/user
3545 0 -rw-rw-r-- 1 cc1 1001 0 Jun 10 20:23 /data/user1.tst
3521 0 lrwxrwxrwx 1 root root 18 Jun 9 21:20 /data/xdg/systemd/user -> ../../systemd/user
1781 4 drwx------ 2 root root 4096 Jun 9 21:22 /data/selinux/targeted/active/modules/100/udev
2532 4 drwx------ 2 root root 4096 Jun 9 21:22 /data/selinux/targeted/active/modules/100/uucp
###以上-ls时针对()的结果
范例:
[root@centos8 ~]#find /etc/ -type d -o -type l |wc -l
307
[root@centos8 ~]#find /etc/ -type d -o -type l -ls |wc -l
101
[root@centos8 ~]#find /etc/ \( -type d -o -type l \) -ls |wc -l
307
范例:
[root@centos-full data]# find /data ! \( -user root -name "*.txt" \)
等同于:
[root@centos-full data]# find /data ! -user root ! -name "*.txt"
-
德·摩根定律: (非 A) 或 (非 B) = 非(A 且 B) (非 A) 且 (非 B) = 非(A 或 B)
示例:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
示例:
###找出/tmp目录下,属主不是root,且文件名不以f开头的文件
find /tmp \( -not -user root -a -not -name 'f*' \) -ls
find /tmp -not \( -user root -o -name 'f*' \) –ls
示例:
find -user joe -group joe
find -user joe -not -group joe
find -user joe -o -user jane
find -not \( -user joe -o -user jane \)
find / -user joe -o -uid 500
6.2.1.7 排除目录
范例:
#查找/etc/下,除/etc/security目录的其它所有.conf后缀的文件
find /etc -path '/etc/security' -a -prune -o -name "*.conf"
#查找/etc/下,除/etc/security和/etc/systemd,/etc/dbus-1三个目录的所有.conf后缀的文件
find /etc \( -path "/etc/security" -o -path "/etc/systemd" -o -path "/etc/dbus-1" \) -a -prune -o -name "*.conf"
#排除/proc和/sys目录
find / \( -path "/sys" -o -path "/proc" \) -a -prune -o -type f -a -mmin -1
6.2.1.8 根据文件大小来查找
- -size [+|-]#UNIT
- 常用单位:k, M, G,c(byte)
- #UNIT: (#-1, #]
- 如:6k 表示(5k,6k]
- -#UNIT:[0,#-1]
- 如:-6k 表示[0,5k]
- +#UNIT:(#, ∞ )
- 如:+6k 表示(6k ,∞
范例:
find / -size +10G
[root@centos8 ~]#find / -size +10G
/proc/kcore
find: ‘/proc/25229/task/25229/fd/6’: No such file or directory
find: ‘/proc/25229/task/25229/fdinfo/6’: No such file or directory
find: ‘/proc/25229/fd/5’: No such file or directory
find: ‘/proc/25229/fdinfo/5’: No such file or directory
[root@centos8 ~]#ll -h /proc/kcore
-r-------- 1 root root 128T Dec 14 2020 /proc/kcore
[root@centos8 ~]#du -sh /proc/kcore
0 /proc/kcore
6.2.1.9 根据时间戳
- 以“天”为单位
- -atime [+|-]#,
- #: 表示[#,#+1) 注意此处与文件大小的表示不同
- +#: 表示[#+1, ∞ ]
- -#: 表示[0,#)
- -mtime
- -ctime
- -atime [+|-]#,
- 以“分钟”为单位
- -amin
- -mmin
- -cmin
6.2.1.10 根据权限查找
-
-perm [/|-]MODE
- MODE: 精确权限匹配
- /MODE:任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+从centos7开始淘汰
-
-MODE:每一类对象都必须同时拥有指定权限,与关系
-
0 表示不关注
-
示例:
-
find -perm 755 会匹配权限模式恰好是755的文件 只要当任意人有写权限时,find -perm +222就会匹配 只有当每个人都有写权限时,find -perm -222才会匹配 只有当其它人(other)有写权限时,find -perm -002才会匹配
范例:
[root@cc1 data]# ll
total 0
---x--x--x. 1 root root 0 Jun 16 20:12 f1
---------x. 1 root root 0 Jun 16 20:14 f2
------x---. 1 root root 0 Jun 16 20:14 f3
[root@cc1 data]# find -perm -001
.
./f1
./f2
[root@cc1 data]# find -perm -011
.
./f1
[root@cc1 data]# find -perm 011
[root@cc1 data]#
6.2.1.11 正则表达式
范例:
find /you/find/dir -regextype posix-extended -regex "regex"
6.2.2 处理动作
- -print:默认的处理动作,显示至屏幕
- -ls:类似于对查找到的文件执行“ls -l”命令
- -delete:删除查找到的文件
- -fls file:查找到的所有文件的长格式信息保存至指定文件中
- -ok COMMAND {} ; 对查找到的每个文件执行由 COMMAND 指定的命令,对于每个文件执行命令之前,都会交互式要求用户确认
- -exec COMMAND {} ; 对查找到的每个文件执行由COMMAND指定的命令
- {}: 用于引用查找到的文件名称自身
- find传递查找到的文件至后面指定的命令时,查找到所有符合条件的文件一次性传递给后面的命令
范例:
[root@cc1 data]# find -type f -ls
67 0 ---x--x--x 1 root root 0 Jun 16 20:12 ./f1
68 0 ---------x 1 root root 0 Jun 16 20:14 ./f2
69 0 ------x--- 1 root root 0 Jun 16 20:14 ./f3
[root@cc1 data]# find -type f -fls f4
[root@cc1 data]# cat f4
67 0 ---x--x--x 1 root root 0 Jun 16 20:12 ./f1
68 0 ---------x 1 root root 0 Jun 16 20:14 ./f2
69 0 ------x--- 1 root root 0 Jun 16 20:14 ./f3
70 0 -rw-r--r-- 1 root root 0 Jun 16 20:31 ./f4
###注意! 保存到一个新文件时, 写入的信息可能包括这个新文件
范例: 查找txt后缀的文件并批量复制到bac文件夹下, 同时改名增加.bak
[root@cc1 data]# touch f{1..10}.txt
[root@cc1 data]# mkdir bac
[root@cc1 data]# ls
bac f10.txt f1.txt f2.txt f3.txt f4.txt f5.txt f6.txt f7.txt f8.txt f9.txt
[root@cc1 data]# find -name "*.txt" -exec cp {} /data/bac/{}.bak \;
[root@cc1 data]# ls /data/bac
f10.txt.bak f2.txt.bak f4.txt.bak f6.txt.bak f8.txt.bak
f1.txt.bak f3.txt.bak f5.txt.bak f7.txt.bak f9.txt.bak
范例: 将查找到的10M的大文件移走
[root@cc1 data]# dd if=/dev/zero of=bigfile bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00709919 s, 1.5 GB/s
[root@cc1 data]# find /data -size 10M -ls
88 10240 -rw-r--r-- 1 root root 10485760 Jun 16 20:46 /data/bigfile
[root@cc1 data]# find /data -size 10M -exec mv {} /data/bac \;
[root@cc1 data]# ls /data/bac
bigfile f1.txt.bak f3.txt.bak f5.txt.bak f7.txt.bak f9.txt.bak
f10.txt.bak f2.txt.bak f4.txt.bak f6.txt.bak f8.txt.bak
范例:
#备份配置文件,添加.orig这个扩展名
find -name ".conf" -exec cp {} {}.orig \;
#提示删除存在时间超过3天以上的joe的临时文件
find /tmp -ctime +3 -user joe -ok rm {} \;
#在主目录中寻找可被其它用户写入的文件
find ~ -perm -002 -exec chmod o-w {} \;
#查找/data下的权限为644,后缀为sh的普通文件,增加执行权限
find /data –type f -perm 644 -name "*.sh" –exec chmod 755 {} \;
6.2.3 参数替换xargs
由于很多命令不支持管道|来传递参数,而日常工作中有这个必要,所以就有了xargs命令
xargs用于产生某个命令的参数,xargs 可以读入 stdin 的数据,并且以空格符或回车符将 stdin 的数据分隔成为arguments
注意:文件名或者是其他意义的名词内含有空格符的情况
有些命令不能接受过多参数,命令执行可能会失败,xargs可以解决
find和xargs格式:
find ... | xargs COMMAND
示例:
备份配置文件,添加.orig这个扩展名
find -name “*.conf” -exec cp {} {}.orig \;
提示删除存在时间超过3天以上的joe的临时文件
find /tmp -ctime +3 -user joe -ok rm {} \;
在主目录中寻找可被其它用户写入的文件
find ~ -perm -002 -exec chmod o-w {} \;
查找/data下的权限为644,后缀为sh的普通文件,增加执行权限
find /data –type f -perm 644 -name “*.sh” –exec chmod 755 {} \;
查看/home的目录
find /home –type d -ls
范例:
#显示10个数字
[root@centos8 ~]#seq 10 | xargs
1 2 3 4 5 6 7 8 9 10
#删除当前目录下的大量文件
ls | xargs rm
#
find -name "*.sh" | xargs ls -Sl
[root@centos8 data]#echo {1..10} |xargs
1 2 3 4 5 6 7 8 9 10
[root@centos8 data]#echo {1..10} |xargs -n1
1
2
3
4
5
6
7
8
9
10
[root@centos8 data]#echo {1..10} |xargs -n2
1 2
3 4
5 6
7 8
9 10
#批量创建和删除用户
echo user{1..10} |xargs -n1 useradd
echo user{1..100} | xargs -n1 userdel -r
#这个命令是错误的
find /sbin/ -perm /700 | ls -l
#查找有特殊权限的文件,并排序
find /bin/ -perm /7000 | xargs ls -Sl
#此命令和上面有何区别?
find /bin/ -perm -7000 | xargs ls -Sl
#以字符nul分隔
find -type f -name "*.txt” -print0 | xargs -0 rm
#并发执行多个进程
seq 100 |xargs -i -P10 wget -P /data http://10.0.0.8/{}.html
#并行下载bilibili视频
yum install python3-pip -y
pip3 install you-get
seq 10 | xargs -i -P3 you-get https://www.bilibili.com/video/BV1HZ4y1p7Bf?p={}