Linux基础12 locate命令, find命令

文件查找

  • 非实时查找(数据库查找):locate
  • 实时查找:find

 

locate:

  • locate 查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db
  • 索引的构建是在系统较为空闲时自动进行(周期任务),执行updatedb可以更新数据库
  • 索引构建过程需要遍历整个根文件系统,很消耗资源
  • locate和update命令来自于mlocate包

工作特点:

  • 查找速度快
  • 模糊查找
  • 非实时查找
  • 搜索的是文件全路径,不仅仅是文件名
  • 可能只搜索用户具备读取和执行权限的目录
#如果没有程序,可先安装
#rehl系列
yum install -y mlocate

#ubuntu
apt install -y Plocate
格式
locate [OPTION]... [PATTERN]...

#常用选项
-A|--all             #输出所有能匹配到的文件名,不管文件是否存在
-b|--basename         #仅匹配文件名部份,而不匹配路径中的内容
-c|--count             #只输出找到的数量
-d|--database DBPATH   #指定数据库
-e|--existing         #仅打印当前现有文件的条目
-L|--follow         #遇到软链接时则跟随软链接去其对应的目标文件中查找 (默认)
-i|--ignore-case       #忽略大小写
-l|--limit|-n N #只显示前N条匹配数据
-P|--nofollow, -H     #不跟随软链
-r|--regexp REGEXP     #使用基本正则表达式
--regex           #使用扩展正则表达式
-s|--stdio             #忽略向后兼容
-w|--wholename         #全路径匹配,就是只要在路径里面出现关键字(默认)
#查找名字带conf的所有文件
[root@ubuntu ~]#locate conf

#实际上是通过这个索引名单库查找,有可能新变化的没记录到库里,可以手动刷新
[root@ubuntu2204 ~]# ll /var/lib/plocate/plocate.db
-rw-r----- 1 root plocate 3142215 May 10 12:17 /var/lib/plocate/plocate.db

#刷新库(之后locate就能查到)
[root@ubuntu2204 ~]# updatedb
案例:
#搜索名称或路径中包含“conf”的文件
[root@ubuntu2204 ~]# locate conf
#搜索ect目录中以a开头的文件或目录,路径包含写法
[root@ubuntu2204 ~]# locate /etc/a

#仅搜索文件名中包含share 的内容
[root@ubuntu2204 ~]# locate -b share
#显示数量
[root@ubuntu2204 ~]# locate -c conf
#显示前10条
[root@ubuntu2204 ~]# locate -n 10 conf

#使用基本正则表达式 [root@ubuntu2204 ~]# locate -r '\.conf$' #指定数据库路径 [root@ubuntu2204 ~]# locate -d /tmp/nofile conf locate: can not stat () `/tmp/nofile': No such file or directory #安静模式,不输出错误信息,新版本中没有 -q 选项 [root@ubuntu2204 ~]# locate -qd /tmp/nofile conf

 

find:

find 是实时查找工具,通过遍历指定路径完成文件查找;

工作特点:

  • 查找速度略慢
  • 精确查找
  • 实时查找
  • 查找条件丰富
  • 可能只搜索用户具备读取和执行权限的目录

语法:

命令  路径       选项      表达式         动作
find [path...] [options] [expression] [action]

 

1.以名字和inode来查找文件
find:

-name name #支持使用glob,如:*, ?, [], [^],通配符要加双引号引起来
-iname name #不区分字母大小写
-inum number #按inode号查找
-samefile name #相同inode号的文件
-links n   #链接数为n的文件
-regex "PATTERN"   #以PATTERN匹配整个文件路径,而非文件名称


在/etc/下找到以.sh结尾的文件

[root@oldboyedu ~]# find /etc/ -name '*.sh'
[root@oldboyedu ~]# find /etc/ -name '*.sh' -ls  # -ls参数可能显示不全,建议后面接|xargs ls -l显示
# 同时查找根目录下名为1.txt,2.txt的文件和名字带a的目录
[root@oldboyedu ~]# find / \( -type f -name '1.txt' -o -name '2.txt' \) -o \( -type d -name '*a*' \)
#正则表达式
[root@ubuntu2204 ~]# find -regex ".*test-[a-z].*"
./test-a.log
./test-a.txt
./test-b.log
./test-b.txt
#正则表达式,路径匹配
[root@ubuntu2204 ~]# find -regex ".*dir3.*"
./dir1/dir2/dir3
./dir1/dir2/dir3/fx
./dir1/dir2/dir3/fy
#正则表达式,路径匹配
[root@ubuntu2204 ~]# find -regex ".*dir3$"
./dir1/dir2/dir3


2.按文件类型查找
-type

文件类型:
d:目录(directory)
f:文件(file)
c:字符设备
b:块设备
l:软链接文件
s:套接字文件(socket)
p:管道文件

[root@oldboyedu ~]# find /dev -type d -ls

# 查找/etc/目录下所有带conf的文件
[root@oldboyedu ~]# find /etc/ -type f -name '*conf*'

# 查找当前系统中,所有的管道文件
[root@oldboyedu ~]# find / -type p
/run/systemd/inhibit/1.ref
/run/systemd/sessions/1.ref
/run/systemd/initctl/fifo
[root@oldboyedu ~]# find / -type p -ls
39101 0 prw------- 1 root root 0 Jul 4 17:18 /run/systemd/inhibit/1.ref
41084 0 prw------- 1 root root 0 Jul 4 17:18 /run/systemd/sessions/1.ref
21199 0 prw------- 1 root root 0 Jul 4 17:18 /run/systemd/initctl/fifo

 

3.根据文件的大小查找
-size:
+:大于
:等于
-:小于

大小单位
b
k
M
G
查找/目录下大于1G的所有文件
[root@oldboyedu ~]# find / -size +1G
查找/目录下等于1G的所有文件(等于好像不准,小于的也会包含)
[root@oldboyedu ~]# find / -size 1G

查找一个脚本,名字带con
[root@oldboyedu ~]# find / -name '*.sh' -name '*con*'

-a:多个条件同时满足
-o:或者,多个条件有一个满足即可
!:取反

# 查找一个脚本,名字不带con
[root@oldboyedu ~]# find / -name '*.sh' ! -name '*con*'

 

 

4.根据时间查找文件
-mtime: # 对应修改时间
+n:寻找n天之前(当天的不算)
-n:查找n天内的文件(当天的文件算在内)
n:查找第n的文件(当天的不算)

-atime:  # 创建时间

例: find /root -mtime -7 # 查找/root下7天内的所有文件
find /root -mtime +7|xargs rm -f # 删除7天以前的所有文件
find /root -mtime +7 -delete # 删除(-delete有缺陷,无法删除非空文件,建议使用|xargs rm -f)
find /tmp/ ! -mtime -30 # !取反,查30内除外的所有文件
find / -atime +3 -name '*.log' -type f  # 查找创建时间3天以前的,结尾是.log的文件

 

5.根据用户来查找文件
-user:指定文件属主用户
-group:指定文件属组

-nouser:查找没有属主的文件
-nogroup:查找没有属组的文件

-uid UserID #查找属主为指定的UID号的文件

-gid GroupID #查找属组为指定的GID号的文件

[root@oldboyedu ~]# find /home/ -user zls -a -group
[root@oldboyedu ~]# find /home/ -user zls -group root
[root@oldboyedu ~]# touch /home/123.txt
[root@oldboyedu ~]# chown zls.root /home/123.txt
[root@oldboyedu ~]# find /home/ -user zls -group root
//查找没有属主(有属主id,但是对应用户不在了)
[root@zls ~]# find /home -nouser
//查找没有属组
[root@zls ~]# find /home -nogroup
[root@oldboyedu ~]# find /home -nogroup -nouser
// 查找7天内属主不是root也不是postfix的文件
[root@oldboyedu ~]# find /var/ -mtime +7 ! -user root -a ! -user postfix -ls

 

$() 和 `` :将引起 来的部分当成一个命令执行。

6.根据权限查找
-perm
644:精确查找
-644:模糊查找(权限位上必须包含查找的对应权限)

/222:取反,没有222权限

例: find -perm 644 # 查找644权限的文件

find -perm 644 -type f # 查找644权限的文件
ls -l $(find -perm 644 -type f) # ls显示所有find查询到的结果
find /etc/ -perm /222 -type f # 查找没有222权限的文件
find /etc/ ! -perm -222 -type f # 查找/etc目录下至少有一类用户没有写权限的文件

 

7.find的动作 action

-print      免费赠送的
-ls           查看文件的详细信息 ls -li
-delete     删除文件(有缺陷,无法删除非空文件, 建议使用|xargs rm -f 或者-exec rm -f)
-ok         -ok {} \; # ;通过\转义, 否则会报错 会提示是否要操作, 一般像cp使用exec
-exec     -exec {} \; 不会提示是否要操作(语法麻烦, 执行效率低(cp/删除为一个个拷贝), 建议用xargs连接进行cp)

# 查找/tmp下15天以前的文件删除
[root@oldboyedu ~]# find /tmp -type f -mtime +15|xargs rm -f
[root@oldboyedu ~]# find /tmp -type f -mtime +15 -exec rm -f {} \;

 

# 把/data目录中所有的以*.txt的文件复制到/tmp目录下
find /data -type f -name "*.txt" |xargs cp -t /tmp # -t 目标位置替换

find /data -type f -name "*.txt" |xargs -I {} cp {} /tmp # -I指定占位符 {}看作一个整体


find /data -type f -name "*.txt" -exec cp {} /tmp \; # 需要命令分割; 
 \进行转义

cp $(find /data -type f -name "*.txt") /tmp

cp `find /data -type f -name "*.txt"` /tmp

 

8.按目录层级查找

-maxdepth N #最大搜索目录深度,指定目录下的文件为第1级
-mindepth N #最小搜索目录深度
# 查找/root/etc/下一级目录,耳机目录里的文件
[root@oldboyedu ~]# find /root/etc/ -maxdepth 2 -type f
# 查找/root/etc/下一级目录,耳机目录里的文件,压缩
[root@oldboyedu ~]# find /root/etc/ -maxdepth 2 -type f|xargs gzip
# 注意: 如果最后接|gzip, 等于把找到的标准输出直接传给gzip会报错

9.空文件或目录

-empty #空文件或空目录

#空文件或空目录
[root@ubuntu2204 ~]# find dir1/dir2/dir3/ -empty
dir1/dir2/dir3/fx
dir1/dir2/dir3/fy
dir1/dir2/dir3/dir4
#查找空目录
[root@ubuntu2204 ~]# find dir1/dir2/dir3/ -empty -type d
dir1/dir2/dir3/dir4
#查找空文件
[root@ubuntu2204 ~]# find dir1/dir2/dir3/ -empty -type f
dir1/dir2/dir3/fx
dir1/dir2/dir3/fy

 

10.组合条件

-a #与,多条件默认就是与关系,可省略
-o #
-not|! #

#默认 -a, 可省略
[root@ubuntu2204 ~]# find -name "*log" -a -type f
./test-a.log
./test-b.log
./test-A.log
./test-B.log
#
[root@ubuntu2204 ~]# find -name "test*log" -o -name "test*txt"
./test-a.log
./test-a.txt
./test-b.log
./test-b.txt
#
[root@ubuntu2204 ~]# find dir1/dir2/dir3/ -empty -not -type d 
dir1/dir2/dir3/fx
dir1/dir2/dir3/fy

#
[root@ubuntu2204 ~]# find dir1/dir2/dir3/ -empty ! -type d 
dir1/dir2/dir3/fx
dir1/dir2/dir3/fy
#注意:ls如果多条件会只列出后面的(这种情况用括号括起来)
#此处 ls 只列出了后一个条件的匹配
[root@ubuntu2204 ~]# find -user jose -o -name "*log" -ls
138733453      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-a.log
138733455      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-b.log
138733459      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-A.log
138733461      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-B.log

#把条件括起来才表示全部
[root@ubuntu2204 ~]# find \( -user jose -o -name "*log" \) -ls
202397817      0 -rw-r--r--   1 jose     root            0 Jul 23 10:48 
./dir1/fa.txt
202397821      0 -rw-r--r--   1 jose     root            0 Jul 23 10:48 
./dir1/fb.txt
138733453      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-a.log
138733455      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-b.log
138733459      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-A.log
138733461      0 -rw-r--r--   1 root     root            0 Jul 23 10:30 ./test-B.log
德·摩根定律:
(非A)且(非B)=非(A或B)
(非A)或(非B)=非(A且B)

示例:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)


# !A -a !B
[root@ubuntu2204 ~]# find ! -name "f*" -a ! -name "dir*"

# !(A -O b)
[root@ubuntu2204 ~]# find ./ ! \( -name "f*" -o -name "dir*" \)

# !A -o !B
[root@ubuntu2204 ~]# find ! -type f -o ! -empty

# !(A -a B)
[root@ubuntu2204 ~]# find ! \( -type f -a -empty \)

 

posted @ 2023-01-10 17:10  战斗小人  阅读(500)  评论(0编辑  收藏  举报