首页 > 代码库 > linux 搜索工具
linux 搜索工具
大家好!本文为大家介绍linux 的搜索工具:locate、find,更精确的查找工具。之前我们学过ls |grep 也能达到搜索文件的功能,但ls是基于文件名的查找,虽然搭配grep能按照一定的条件去查找文件,又因为每个文件的格式不唯一,所以这种方法也不总适用。
下面为大家介绍简单精确的查找工具:
1、locate: 基于数据库的查询,非实时性,对新创建的文件需要更新数据库。local是基于文件全路径的模糊查询,查询时会判断权限
格式:locate KEYWORD
-i 忽略大小写
-n X 只列举前N个匹配的项目
updatedb 更新locate数据库 /var/lib/mlocate/mlocate.db
-r 支持正则
eg: locate conf 搜索名称或路径中带有“conf ”的文件
locate -r ‘\.conf$’ 使用Regex 来搜索以“.conf
2、find : 实时查询,速度肯定没locate快。但它可以基于文件大小、属主、属组、访问时间、文件名、文件类型、硬链接等更精确的查找方式。查找时也需要具有相应权限(rx)
(1)语法: find [OPTION]... [ 查找路径] [ 查找条件] [ 处理动作]
查找路径:指定具体目标路径;默认为当前目录
查找条件:指定的查找标准,可以文件名、大小、类型、
权限等标准进行;默认为找出指定路径下的所有文件
处理动作:对符合条件的文件做操作,默认输出至屏幕
(2)find
-maxdepth level 最大搜索深度
-minxdepth level 最小搜索深度
-name 基于名称的精确查找,支持通配符*, ?, [], [^]
eg:find -name “my*” 搜索当前目录(含子目录)中,所有文件名以my开头的文件
-iname 基于名称忽略大小写的精确查找查找
-empty : 空的档案-gid n or -group name : gid 是 n 或是 group 名称是 name
-ipath p, -path p : 匹配一个路径名,ipath 会忽略大小写
-inum 基于inode查找
-samefile "文件名" 基于相同inode号的查找(查找硬链接)
-links n 硬链接数为n的文件
-regex “PATTERN”支持正则 默认为(emacs标准),匹配全路径,而不只是文件名
eg:find -regex ".*f[1-9]" 因为匹配的是全路径所以".*"要加到前面
-regextype egrep -regex 支持egrep同标准的正则
-user 用户名 基于文件owner的查找
-group 组名 基于文件group的查找
-uid userid 基于文件uid的查找
-gid groupid 基于文件gid的查找
-nouser 查找没有owner的文件
-nogroup 查找没有group的文件
-type 基于文件类型的查找
? f: 普通文件
? d: 目录文件
? l: 符号链接文件
? s:套接字文件
? b: 块设备文件
? c: 字符设备文件
? p: 管道文件
(3)组合条件:-a与 、-o或 、-not=! 非
德摩根定律:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
eg: find /tmp \( -not -user root -a -not -name ‘f*‘ \) -ls
find /tmp -not \( -user root -o -name ‘f*‘ \) –ls
需要注意的是f*表示文件名要以f开头
*f*表示只要文件名包含f即可
\(代表一个复杂表达式的开始
\)代表一个复杂表达式的结束
(4)排除目录
find [-path ..] [expression] 在路径列表的后面的是表达式
-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o -print 的简写表达式按顺序求值, -a 和 -o 都是短路求值,与 shell 的 && 和 || 类似如果 -path "/usr/sam" 为真,则求值 -prune , -prune 返回真,与逻辑表达式为真;否则不求值 -prune,与逻辑表达式为假。如果 -path "/usr/sam" -a -prune 为假,则求值 -print ,-print返回真,或逻辑表达式为真;否则不求值 -print,或逻辑表达式为真。
eg:find /etc -path ‘/etc/sane.d‘ -a -prune -o -name "*.conf"
在/etc目录下查找文件名以.conf结尾的文件(除/etc/sane.d目录不查询)
find /etc \( -path ‘/etc/sane.d‘ -o -path ‘/etc/fonts‘ \) -a -prune -o -name "*.conf"
在/etc目录下查找文件名以.conf结尾的文件(除/etc/sane.d目录、/etc/fonts不查询)
(5)基于文件大小查找
-size [+|-]#UNIT 根据文件大小来查找
常用单位:k, M, G,c(byte)
#UNIT: (#-1, #]如:6k 表示(5k,6k]
-#UNIT:[0,#-1]如:-6k 表示[0,5k]
+#UNIT:(#,∞)如:+6k 表示(6k,∞)
find 中要想使用正规正则表达式,需要用选项 -regex "pattern",
注意 find 的常用选项 -name 是不支持正则表达式的,充其量只能说 -name 选项支持通配符 * ? []
(6)基于时间戳查找
以“天”为单位;
-atime [+|-]#,
#: [#,#+1)
+#: [#+1,∞]
-#: [0,#)
-mtime
-ctime
以“分钟”为单位:
-amin
-mmin
-cmin
(7)基于权限查找
-perm [ mode|+mode|-mode]
mode:精确权限匹配
+mode[/mode] 任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+ 从centos7开始淘汰
-mode 每一类对象都必须同时拥有指定权限,与关系0 表示不关注
(8)处理动作:
-print 默认
-delete 直接删除所查找到的文件,不询问。
-ls 长列出所查找到的文件
-fls file 将查找到的文件长列出导入到指定文件。
> file
-ok command {} \; 对查找到的每个文件当做下一命令的参数去执行(交互式)
-exec command {} \; 对查找到的每个文件当做下一命令的参数去执行(非交互式)
{}: 用于引用查找到的文件名称自身
那些天走过的弯路:
问题描述:
find -name "f2" -o -name "f3" -a -exec echo {} \;
只会把最后一个查找条件匹配的结果传递给exec后的命令做参数
find \( -name "f2" -o -name "f3" \) -a -exec echo {} \;
会把括号里所有的查询结果,作为参数传递给exec后的命令做参数
困扰:
find的查询顺序不应该是顺序执行么?当 f2 没匹配到返回false值,再去匹配第二个条件f3。
那么应该只要匹配到一个条件返回一个true,就会通过-exec传递给命令了吧?
经过反复调试,发现find -name "f2" -o -name "f3" -a -exec echo {} \;
这种写法只会把-exec前的条件匹配到的结果传递给后面的命令,而与find的查询顺序毫无关系
原理剖析:
find -name "f2" -o -name "f3" -exec echo {} \;
(1)不加括号会把-name "f3" -a -exec echo {} \;看成一个整体
(2)-exec 会把结果传递给命令,不会再显示在标准输出(相当于输出重定向)
总结:
find把条件看成了两个部分: -name "f2" 或者 -name "f3" -exec echo {}
(1)先来说f3,匹配到以后会把查询结果传递给exec后的命令,然后执行
(2)-name "f2" 的查询结果,原本应该在标准输出显示出来,但因为把结果传递给了-exec,
而exec又只传递f3的匹配结果,所以f2没有显示出来
练习:
1、查找/var目录下属主为root,且属组为mail的所有文件
find /var -user root -a -group mail -ls
2、查找/var目录下不属于root、lp、gdm的所有文件
find /var -not \( -user root -o -user lp -o -user gdm \) -ls
3、查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是postfix的文件
find /var/ -mtime -7 -not -user root -not -user postfix -ls
4、查找当前系统上没有属主或属组,且最近一个周内曾被访问过的文件
find / -nouser -o -nogroup -a -atime -7 -ls
5、查找/etc目录下大于1M且类型为普通文件的所有文件
find /etc/ -size +1M -a -type f -ls
6、查找/etc目录下所有用户都没有写权限的文件
find /etc ! -perm /222 -ls
7、查找/etc目录下至少有一类用户没有执行权限的文件
find /etc ! -perm -111 -ls
8、查找/etc/init.d目录下,所有用户都有执行权限,且其它
用户有写权限的文件
find /etc/init.d/ -perm -113 -ls
9、查找名字符合正则表达式的文件,注意前面的‘.*’(查找到的文件带有目录)
find ./ -regex .*so.*\.gz
10、查找目录并列出目录下的文件(为找到的每一个目录单独执行ls命令,没有选项-print时文件列表前一行不会显示目录名称)
find ./ -type d -print -exec ls {} \;
11、查找目录并列出目录下的文件(为找到的每一个目录单独执行ls命令,执行命令前需要确认)
find ./ -type d -ok ls {} \;
linux 搜索工具
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。