文件查找

在文件系统上查找符合条件的文件

文件查找:

非实时查找(数据库查找):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