文件查找
在文件系统上查找符合条件的文件
文件查找:
- 非实时查找(数据库查找):locate
- 实时查找:find
locate
- locate 查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db
- 索引的构建是在系统较为空闲时自动进行(周期性任务),执行updatedb可以更新数据库
- 索引构建过程需要遍历整个根文件系统,很消耗资源
- locate和updatedb命令来自于mlocate包
工作特点:
- 查找速度快
- 模糊查找
- 非实时查找
- 搜索的是文件的全路径,不仅仅是文件名
- 可能只搜索用户具备读取和执行权限的目录
格式
locate [OPTION]... [PATTERN]...
常用选项
-i 不区分大小写搜索
-n N 只列举前N个匹配的项目
-r 使用基本正则表达式
范例
#搜索名称或路径中包含“conf”的文件
locate conf
#使用Regex来搜索以“.conf”结尾的文件
locate -r '\.conf$'
范例:locatedb创建数据库
[19:33:32 root@centos7 ~]#yum install -y mlocate
[19:33:32 root@centos7 ~]#locate conflocate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
[19:33:32 root@centos7 ~]#updatedb
[19:33:32 root@centos7 ~]#ll /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 1041065 Jun 11 20:08 /var/lib/mlocate/mlocate.db
[19:33:32 root@centos7 ~]#locate -n 3 conf
/backup/etc2020-08-09/GeoIP.conf
/backup/etc2020-08-09/GeoIP.conf.default
/backup/etc2020-08-09/asound.conf
范例:文件新创建和删除,无法马上更新locate数据库
[19:36:07 root@centos7 ~]#touch test.log
[19:36:18 root@centos7 ~]#locate test.log
[19:36:27 root@centos7 ~]#
[19:36:37 root@centos7 ~]#ls
anaconda-ks.cfg color.txt fa.txt fb.txt test.log
[19:37:07 root@centos7 ~]#updatedb
[19:37:15 root@centos7 ~]#locate test.log
/root/test.log
[19:37:47 root@centos7 ~]#rm -rf test.log
[19:38:08 root@centos7 ~]#locate test.log
/root/test.log
范例:
[19:39:33 root@centos7 ~]#locate -n 10 -ir '\.conf$'
/backup/etc2020-08-09/GeoIP.conf
/backup/etc2020-08-09/asound.conf
/backup/etc2020-08-09/dracut.conf
/backup/etc2020-08-09/e2fsck.conf
/backup/etc2020-08-09/fuse.conf
/backup/etc2020-08-09/host.conf
/backup/etc2020-08-09/kdump.conf
/backup/etc2020-08-09/krb5.conf
/backup/etc2020-08-09/ld.so.conf
/backup/etc2020-08-09/libaudit.conf
find
find 是实时查找工具,通过遍历指定路径完成文件查找
工作特点:
- 查找速度略慢
- 精确查找
- 实时查找
- 查找条件丰富
- 可能只搜索用户具备读取和执行权限的目录
格式
find [OPTION]... [查找路径] [查找条件] [处理动作]
查找路径:指定具体目标路径;默认为当前目录
查找条件:指定的查找标准,可以文件名、大小、类型、权限等标准进行;默认为找出指定路径下的所有文件
处理动作:对符合条件的文件做操作,默认输出至屏幕
指定搜索目录层级
-maxdepth level 最大搜索目录深度,指定目录下的文件为第1级
-mindepth level 最小搜索目录深度
范例
find /etc/ -mindepth 2 -maxdepth 2
对每个目录先处理目录内的文件,再处理目录本身
-depth -d
范例
[19:46:27 root@centos7 ~]#tree /data/test/
/data/test/
├── f1.txt
├── f2.txt
├── test1
└── test2
├── f3.txt
└── f4.txt
2 directories, 4 files
[19:46:35 root@centos7 ~]#find /data/test
/data/test
/data/test/test1
/data/test/test2
/data/test/test2/f3.txt
/data/test/test2/f4.txt
/data/test/f1.txt
/data/test/f2.txt
[19:46:42 root@centos7 ~]#find /data/test -depth
/data/test/test1
/data/test/test2/f3.txt
/data/test/test2/f4.txt
/data/test/test2
/data/test/f1.txt
/data/test/f2.txt
/data/test
根据文件名和inode查找
-name "文件名称":支持使用glob,如:*, ?, [], [^],通配符要加双引号引起来
-iname "文件名称":不区分字母大小写
-inum n 按inode号查找
-samefile name 相同inode号的文件
-links n 链接数为n的文件
-regex “PATTERN”:#以PATTERN匹配整个文件路径,而非文件名称
范例
[19:50:42 root@centos7 ~]#find -name test1.log
./test1.log
[19:50:46 root@centos7 ~]#find -iname test1.log
./test1.log
[19:51:27 root@centos7 ~]#find / -name "*.log"
/data/user.log
/root/test1.log
/var/log/tuned/tuned.log
/var/log/audit/audit.log
/var/log/anaconda/anaconda.log
/var/log/anaconda/X.log
/var/log/anaconda/program.log
[19:52:07 root@centos7 ~]#find /data -name "*.txt"
/data/scripts/scrip.txt
/data/etc_2020-08-06/pki/nssdb/pkcs11.txt
/data/test/test2/f3.txt
/data/test/test2/f4.txt
/data/test/f1.txt
/data/test/f2.txt
[19:52:30 root@centos7 ~]#find -regex ".*\.txt$"
./color.txt
./fa.txt
./fb.txt
根据属主、属组查找
-user USERNAME:查找属主为指定用户(UID)的文件
-group GRPNAME: 查找属组为指定组(GID)的文件
-uid UserID:查找属主为指定的UID号的文件
-gid GroupID:查找属组为指定的GID号的文件
-nouser:查找没有属主的文件
-nogroup:查找没有属组的文件
范例
[19:53:06 root@centos7 ~]#find -user root
.
./.bash_logout
./.bash_profile
./.cshrc
./.tcshrc
[19:55:31 root@centos7 ~]#find -group root
.
./.bash_logout
./.bash_profile
./.cshrc
./.tcshrc
[19:55:56 root@centos7 ~]#find /home -uid 1000
/home/ding
/home/ding/.bash_logout
/home/ding/.bash_profile
/home/ding/.bashrc
/home/ding/.bash_history
[19:56:27 root@centos7 ~]#find /home -gid 1000
/home/ding
/home/ding/.bash_logout
/home/ding/.bash_profile
/home/ding/.bashrc
/home/ding/.bash_history
[19:56:57 root@centos7 ~]#find /home -nouser
/home/lulu
/home/lulu/.bash_logout
/home/lulu/.bash_profile
/home/lulu/.bashrc
[19:57:09 root@centos7 ~]#find /home -nogroup
/home/lulu
/home/lulu/.bash_logout
/home/lulu/.bash_profile
/home/lulu/.bashrc
根据文件类型查找
-type TYPETYPE
可以是以下形式:
f: 普通文件
d: 目录文件
l: 符号链接文件
s:套接字文件
b: 块设备文件
c: 字符设备文件
p: 管道文件
范例
[20:00:44 root@centos7 ~]#find /data -type b -ls
[20:00:56 root@centos7 ~]#find /data -type l -ls
空文件或目录
-enpty
范例
[20:03:07 root@centos7 ~]#find /data/ -empty
[20:03:07 root@centos7 ~]#find /data/ -empty -type -d
组合条件
与:-a ,默认多个条件是与关系
或:-o
非:-not !
范例
[20:05:23 root@centos7 ~]#find /etc/ -type d -o -type l |wc -l
691
[20:05:44 root@centos7 ~]#find /etc/ -type d -o -type l -ls |wc -l
92
[20:06:39 root@centos7 ~]#find /etc/ \( -type d -o -type l \) -ls |wc -l
691
总结:与的优先级大于或 ,-type l -ls 等于 -type l -a -ls
德-摩根定律
- (非 A) 或 (非 B) = 非(A 且 B)
- (非 A) 且 (非 B) = 非(A 或 B)
示例:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
范例
[20:12:19 root@centos7 ~]#find /home -user ding -group ding
/home/ding
/home/ding/.bash_logout
/home/ding/.bash_profile
/home/ding/.bashrc
/home/ding/.bash_history
[20:12:30 root@centos7 ~]#find /home -user ding -not -group ding
[20:12:44 root@centos7 ~]#find /home -user ding -o -group ding
/home/ding
/home/ding/.bash_logout
/home/ding/.bash_profile
/home/ding/.bashrc
/home/ding/.bash_history
[20:14:08 root@centos7 ~]#find /home -not \( -user ding -o -user xixi \)
/home
/home/zhang
/home/zhang/.bash_logout
/home/zhang/.bash_profile
/home/zhang/.bashrc
[20:15:20 root@centos7 ~]#find /home -user ding -o -user zhang
/home/ding
/home/ding/.bash_logout
/home/ding/.bash_profile
/home/ding/.bashrc
/home/ding/.bash_history
/home/zhang
/home/zhang/.bash_logout
/home/zhang/.bash_profile
/home/zhang/.bashrc
#找出/tmp目录下,属主不是root,且文件名不以f开头的文件
find /tmp \( -not -user root -a -not -name 'f*' \) -ls
find /tmp -not \( -user root -o -name 'f*' \) –ls
排除目录
格式
-path 目录路径 -a -prune
范例
#查找/etc/下,除/etc/sane.d目录的其它所有.conf后缀的文件
[20:24:50 root@centos7 ~]#find /etc -path '/etc/sand.d' -a -prune -o -name "*.conf"
#查找/etc/下,除/etc/sane.d和/etc/fonts两个目录的所有.conf后缀的文件
[20:28:38 root@centos7 ~]#find /etc \( -path '/etc/sand.d' -path '/etc/fonts' \) -a -prune -o -name "*.conf"
#排除/proc和/sys目录,查找根下的一分钟之内被改变文件内容的普通文件
[20:31:39 root@centos7 ~]#find / \( -path “/sys” -o -path “/var” \) -a -prune -o -type f -a -mmin -1
根据文件大小查找
-size [+|-]#UNIT #常用单位:k, M, G,c(byte),注意大小写敏感
#UNIT: #表示(#-1, #],如:6k 表示(5k,6k]
-#UNIT #表示[0,#-1],如:-6k 表示[0,5k]
+#UNIT #表示(#,∞),如:+6k 表示(6k,∞)
范例
find /etc -size +1M
根据时间戳查找
#以“天”为单位
-atime [+|-]#
# #表示[#,#+1)如:3 表示第3-4天
+# #表示[#+1,∞]如:+3 表示4天以后
-# #表示[0,#)如:-3 表示3天以内
-mtime
-ctime
#以“分钟”为单位
-amin
-mmin
-cmin
根据权限查找
-perm [/|-]MODE
MODE: 精确权限匹配
/MODE:任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+从CentOS 7开始淘汰
-MODE:每一类对象都必须同时拥有指定权限,与关系0 表示不关注
说明:
find -perm 755会匹配权限模式恰好是755的文件
只要当任意人有写权限时,find -perm /222就会匹配只有当每个人都有写权限时,find -perm -222才会匹配
只有当其它人(other)有写权限时,find -perm -002才会匹配
范例
[20:55:35 root@centos7 ~]#ll
total 16
-rw-------. 1 root root 1613 Jul 29 08:32 anaconda-ks.cfg
-rw-r--r--. 1 root root 39 Aug 6 14:36 color.txt
-rw-r--r--. 1 root root 21 Aug 6 15:29 fa.txt
-rw-r--r--. 1 root root 12 Aug 6 15:42 fb.txt
-rw-r--r--. 1 root root 0 Aug 10 19:37 test1.log
[20:55:18 root@centos7 ~]#find -perm 644
./.bash_logout
./.bash_profile
./.cshrc
./.tcshrc
./color.txt
./fa.txt
./fb.txt
./.bashrc
./.vimrc
./test1.log
[20:58:21 root@centos7 ~]#find -perm /600
.
./.bash_logout
./.bash_profile
./.cshrc
./.tcshrc
./anaconda-ks.cfg
./.bash_history
./color.txt
./fa.txt
./fb.txt
./.bashrc
./.vimrc
./.viminfo
./test1.log
[20:58:47 root@centos7 ~]#find -perm -044
./.bash_logout
./.bash_profile
./.cshrc
./.tcshrc
./color.txt
./fa.txt
./fb.txt
./.bashrc
./.vimrc
./test1.log
正则表达式
-regextype type
Changes the regular expression syntax understood by -regex and -iregex tests which occur later on the command line. Currently-implemented types are emacs (this is the default), posix-awk, posix-basic, posix-egrep and posix-extended.
-regextype类型更改稍后在命令行上进行的-regex和-iregex测试所理解的正则表达式语法。当前实现的类型是emacs(这是默认的)、posix-awk、posix-basic、posix-egrep和posix-extended。
-regex pattern
File name matches regular expression pattern. This is a match on the whole path, not a search. For example, to match a file named `./fubar3', you can use the regular expression `.*bar.' or `.*b.*3', but not `f.*r3'. The regular expressions understood by find are by default Emacs Regular Expressions, but this can be changed with the -regextype option.
-regex模式文件名匹配正则表达式模式。这是对整个路径的匹配,而不是搜索。例如,匹配名为'的文件。/fubar3',你可以使用正则表达式' .*bar。”或“。* b。乘以3'而不是f *r3'find所理解的正则表达式在缺省情况下是Emacs正则表达式,但是可以使用-regextype选项更改
范例
find /you/find/dir -regextype posix-extended -regex "regex"
处理动作
-print:默认的处理动作,显示至屏幕
-ls:类似于对查找到的文件执行"ls -dils"命令格式输出
-fls file:查找到的所有文件的长格式信息保存至指定文件中,相当于-ls > file
-delete:删除查找到的文件,慎用!
-ok COMMAND {} \; 对查找到的每个文件执行由COMMAND指定的命令,对于每个文件执行命令之前,都会交互式要求用户确认
-exec COMMAND {} \; 对查找到的每个文件执行由COMMAND指定的命令{}: 用于引用查找到的文件名称自身
范例
#备份脚本文件,添加.bak这个扩展名
[21:12:44 root@centos7 scripts]#find -name "*.sh" -exec cp {} {}.bak \;
#提示删除存在时间超过3天以上的joe的临时文件
[21:14:04 root@centos7 scripts]#find /tmp -ctime +3 -user joe -exec rm -rf {} \;
#在主目录中寻找可被其它用户写入的文件,并去除写权限
[21:14:04 root@centos7 scripts]#find ~ -prem -002 -exec chmod o-w {} \;
#查找/data下的权限为644,后缀为sh的普通文件,增加执行权限
[21:21:47 root@centos7 scripts]#find /data/ -perm 644 -name "*.sh" -type f -exec chmod a+x {} \;
参数替换 xargs
由于很多命令不支持管道|来传递参数,xargs用于产生某个命令的参数,xargs 可以读入 stdin 的数据,并且以空格符或回车符将 stdin 的数据分隔成为参数
另外,许多命令不能接受过多参数,命令执行可能会失败,xargs 可以解决
注意:文件名或者是其他意义的名词内含有空格符的情况
find 经常和 xargs 命令进行组合,形式如下:
find | xargs COMMAND
范例
#显示10个数字
[21:28:27 root@centos7 scripts]#seq 10 |xargs
1 2 3 4 5 6 7 8 9 10
#删除当前目录下的大量文件
[21:28:31 root@centos7 scripts]#ls |xargs rm
#找出当前目录下以.sh结尾的文件并用ls显示
[21:33:16 root@centos7 scripts]#find -name "*.sh" | xargs ls -sl
[21:33:16 root@centos7 scripts]#echo {1..10} |xargs
1 2 3 4 5 6 7 8 9 10
[21:38:22 root@centos7 scripts]#echo {1..10} |xargs -n1
1
2
3
4
5
6
7
8
9
10
[21:38:26 root@centos7 scripts]#echo {1..10} |xargs -n2
1 2
3 4
5 6
7 8
9 10
#批量创建和删除用户
[21:38:28 root@centos7 scripts]#echo user{1..10} |xargs -n1 useradd
[21:41:18 root@centos7 scripts]#echo user{1..10} |xargs -n1 userdel -r
#这个命令是错误的
find /sbin/ -perm /700 | ls -l
#查找有特殊权限的文件,并排序
[21:46:33 root@centos7 scripts]#find /bin/ -perm /7000 | xargs ls -sl
#此命令和上面有何区别?
find /bin/ -perm -7000 | xargs ls -Sl
总结:xargs接收不到参数时,它会直接执行后面的命令
#以字符null分隔
[21:54:11 root@centos7 ~]#find -name "*.txt" -print0 |xargs -0 rm
#并发执行多个进程
[21:54:11 root@centos7 ~] 100 |xargs -i -P10 wget -P /data http://10.0.0.8/{}.html
#并行下载视频
[21:54:11 root@centos7 ~] 10 | xargs -i -P3 you-get https://www.bilibili.com/video/BV1HZ4y1p7Bf?p={}