linux之find命令详解 linux&shell学习系列

一、find概述

话不多说,先来find --help一下

[hive@lgh test]$ find --help
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression] #使用的语法

default path is the current directory; default expression is -print #默认是当前目录,默认采用的action是-print,如果有设置action,则默认会被覆盖
expression may consist of: operators,options,tests,and actions:

operators (decreasing precedence; -and is implicit where no others are given): #一些重要操作,就像编程里面所用到的,与,非,或这些关系,
      ( EXPR )   ! EXPR   -not EXPR   EXPR1 -a EXPR2   EXPR1 -and EXPR2
      EXPR1 -o EXPR2   EXPR1 -or EXPR2   EXPR1,EXPR2

positional options (always true): -daystart -follow -regextype #总是返回true

normal options (always true,specified before other expressions): #总是返回true
      -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
      --version -xdev -ignore_readdir_race -noignore_readdir_race

tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N   #重点
      -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME
      -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN
      -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE
      -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN
      -readable -writable -executable
      -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N
      -used N -user NAME -xtype [bcdpfls]
      -context CONTEXT


actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print  #重点
      -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit
      -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;
      -execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;

Report (and track progress on fixing) bugs via the findutils bug-reporting
page at http://savannah.gnu.org/ or,if you have no web access,by sending
email to <bug-findutils@gnu.org>.

从上看:find命令的使用语法:

Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

其中expression主要包括operators,and actions

expression may consist of: operators,and actions:

二、find基本原理和实践

find是从左向右处理的,所以表达式的前后顺序不同会造成不同的搜索性能差距。

搜索机制:find的搜索机制是根据表达式返回的true/false决定的,每搜索一次都判断一次是否能确定最终评估结果为true,只有评估的最终结果为true才算是找到。

find首先对整个命令行进行语法解析,并应用给定的options,然后定位到搜索路径path下开始对路径下的文件或子目录进行表达式评估或测试,评估或测试的过程是按照表达式的顺序从左向右进行的(此处不考虑操作符的影响),如果最终表达式的表达式评估为true,则输出(默认)该文件的全路径名

2.1、操作符(operators)

    我相信大家都学过一些编程语言,这里的运算操作符合java中的编程语言一样的意思,其实就是一些与,或,非的操作,都是一些短路的操作,虽然比较简单,但是很有用,接下来我们具体看下这些内容:

(expr)           #优先级最高。为防止括号被shell解释(进入子shell),所以需要转义,即\(...\)
! expr           #对expr的true和false结果取反。同样需要使用引号包围
-not expr        #等价于"! expr"
expr1 expr2      #等同于and操作符。
expr1 -a expr2   #等同于and操作符。
expr1 -and expr2 #首先要求expr1为true,然后expr2以expr1搜索的结果为基础继续检测,然后再返回检测值为true的文件。因为expr2是以expr1结果为基础的,所以如果expr1返回
                 #false,则expr2直接被忽略而不会进行任何操作
expr1 -o expr2   #等同于or操作符
expr1 -or expr2  #只有expr1为假时才评估expr2。
expr1,expr2    #逗号操作符表示列表的意思,expr1和expr2都会被评估,但expr1的true或false是被无视的,只有expr2的结果才是最终状态值。
[hive@lgh test]$ ll
total 8
drwxrwxr-x 2 hive hive 4096 Sep 30 10:06 a
drwxrwxr-x 2 hive hive 4096 Sep 30 10:06 b
-rw-rw-r-- 1 hive hive    0 Sep 30 10:06 c
lrwxrwxrwx 1 hive hive    1 Sep 30 10:08 d -> a
[hive@lgh test]$ find . -type f -a -name c  #打印文件,并且名为c  
./c
[hive@lgh test]$ find . -type f -o -type d  #打印文件或者目录
.
./a
./b
./c

注意:and 的优先级高于 or,and和or操作都是短路操作,先判断第一个条件,and:如果第二个条件不满足,则第二个条件不予判读,or则相反

2.2、选项(options)

     options总是返回true。除了"-daystart",options会影响所有指定的test表达式部分,哪怕是test部分写在options的前面。这是因为options是在命令行被解析完后立即处理的,而test是在检测到文件后才处理的。对于"-daystart"这个选项,它们仅仅影响写在它们后面的test部分,因此,建议将任何options部分写在expression的最前面。

-daystart         #指定以每天的开始(凌晨零点)计算关于天的时间,用于改变时间类(-amin,-atime,-cmin,-ctime,-mmin和-mtime)
                  #的计算方式。默认天的计算是从24小时前计算的。例如,当前时间为5月3日17:00,要求搜索出2天内修改过的文件,默认
                  #搜索文件的起点是5月1日17:00,如果使用-daystart,则搜索文件的起点是是5月1日00:00。
                  #注意,该选项只会影响写在它后面的test表达式。
-depth            #搜索到目录时,先处理目录中的文件(子目录),再处理目录本身。对于"-delete"这个action,它隐含"-depth"选项。
-maxdepth levels  #指定tests和actions作用的最大目录深度,只能为非负整数。可以简单理解为目录搜索深度,但并非如此。当
                  #前path目录的层次为1,所以若指定-maxdepth 0将得不到任何结果。
-mindepth levels  #tests和actions不会应用于小于指定深度的目录,"-mindepth 1"表示应用于所有的文件。
-ignore_readdir_race #当无法用stat检测文件信息时(如无权限)会给出下图所示的错误信息,如要忽略该信息,可以使用该选项。

[root@lgh ~]# find /etc -name passwd
/etc/passwd
/etc/pam.d/passwd
[root@lgh ~]# find /etc -maxdepth 1 -name passwd
/etc/passwd
[root@lgh ~]#
[root@lgh ~]# find /etc -maxdepth 2 -mindepth 2 -name passwd  #之返回第二层目录的匹配文件
/etc/pam.d/passwd

如果指定了-depth,则先处理目录中的文件,再处理目录本身。在Linux一切皆文件,子目录也是文件
[hive@lgh test]$ ll total
8 -rw-rw-r-- 1 hive hive 0 Sep 30 10:52 1.bak -rw-rw-r-- 1 hive hive 0 Sep 30 10:52 2.bak -rw-rw-r-- 1 hive hive 0 Sep 30 10:52 3.bak drwxrwxr-x 2 hive hive 4096 Sep 30 10:52 a [hive@lgh test]$ find ../test -depth ../test/3.bak ../test/a/1.txt ../test/a/2.txt ../test/a/3.txt ../test/a #先处理目录a下的文件,才处理a目录 ../test/1.bak ../test/b ../test/2c ../test/d ../test #最后才处理目录

 

2.3、tests

(N can be +N or -N or N)
+n:大于n
-n:小于n
n :精确的等于n

2.3.1、从文件类型判断

-type [bcdpflsD] 

X  #根据文件类型来搜索 
b  #块设备文件
c  #字符设备文件
d  #目录
p  #命名管道文件(FIFO文件)
f  #普通文件
l  #符号链接文件,即软链接文件
s  #套接字文件(socket)
 c
lrwxrwxrwx 1 hive hive    1 Sep 30 10:08 d -> a
[hive@lgh test]$ find . -type l  #查找链接文件
./d

2.3.2、从文件大小判断

-size N[bcwkMG] 

b  #512字节的(默认单位)
c  #1字节的
w  #2字节
k  #1024字节
M  #1024k
G  #1024M

empty:空文件,对于目录来说,则是空目录

 a
[hive@lgh test]$ find -size 1  #文件大小为1字节
./d
[hive@lgh test]$ find -size -2 #文件大小小于2字节c
./d

2.3.3、从文件名后者路径名判断

-name pattern   #文件的basename(不包括其前导目录的纯文件名)能被通配符模式的pattern匹配到。需要注意的是,在find中的通配元字符"*"、"?"和"[]"是能够匹配以点开头的文件的
-iname pattern  #不区分大小的"-name"               
-path pattern   #文件名能被通配符模式的pattern匹配到。此模式下,通配元字符"*"、"?"和"[]"不认为字符"/"或"."是特殊字符,也就是说这两个字符也在通配范围内,所以能匹配这两个字符。    
-ipath pattern  #不区分大小写的"-path"                        
-regex pattern  #文件名能被正则表达式pattern匹配到的文件。正则匹配会匹配整个路径,例如要匹配文件名为"./fubar3"
                #的文件,可以使用".*bar."或".*b.*3",但不能是"f.*r3",默认find使用的正则类型是Emacs正则,但可以使用-regextype来改变正则类型                            
-iregex pattern #不区分大小写的"-regex"
[hive@lgh test]$ ll
total 8
-rw-rw-r-- 1 hive hive    0 Sep 30 10:52 1.bak
-rw-rw-r-- 1 hive hive    0 Sep 30 10:51 1.txt
-rw-rw-r-- 1 hive hive    0 Sep 30 10:52 2.bak
-rw-rw-r-- 1 hive hive    0 Sep 30 10:51 2.txt
-rw-rw-r-- 1 hive hive    0 Sep 30 10:52 3.bak
-rw-rw-r-- 1 hive hive    0 Sep 30 10:51 3.txt
-rw-rw-r-- 1 hive hive    0 Sep 30 10:51 4.txt
drwxrwxr-x 2 hive hive 4096 Sep 30 10:52 a
[hive@lgh test]$ find . -name "*.bak"
./3.bak
./1.bak
./2.bak
[hive@lgh test]$ find . -path "./a/*.txt"
./a/1.txt
./a/2.txt
./a/3.txt
[hive@lgh test]$ find . -regex ".*txt"    #正在匹配
./1.txt
./a/1.txt
./2.txt
./4.txt
./3.txt

2.3.4、从文件权限判断

-perm mode  #精确匹配给定权限的文件。"-perm g=w"将只匹配权限为0020的文件。当然,也可以写成三位数字的权限模式
-perm /mode #匹配任意给定权限位的权限,例如"-perm /640"可以匹配出600,040,700perm的测试
-readable   #具有可读权限的文件。它会考虑acl等的特殊权限,只要是可读就满足。它会忽略掉-perm的测试
-writable   #具有可写权限的文件。它会考虑acl等的特殊权限,只要是可写就满足。它会忽略掉-perm的测试(不是writeable)
# find . -type f -perm 0777 -print
# find / -type f ! -perm 777
# find / -perm 2644
# find / -perm /u=s

2.3.5、从文件所属情况判断

-gid n       #gid为n的文件
-group gname #组名为gname的文件
-uid n       #文件的所有者的uid为n
-user uname  #文件的所有者为uname,也可以指定uid
-nogroup     #匹配那些所属组为数字格式的gid,且此gid没有对应组名的文件
-nouser      #匹配那些所有者为数字格式的uid,且此uid没有对应用户名的文件
# find / -user root -name tecmint.txt
# find /home -user tecmint
# find /home -group developer
# find /home -user tecmint -iname "*.txt"

2.3.6、从文件的时间参数判断

-anewer file:atime比mtime更接近现在的文件。也就是说,文件修改过之后被访问过
-cnewer file:ctime比mtime更接近现在的文件
-newer  file:比给定文件的mtime更接近现在的文件。
-newer[acm]t TIME:atime/ctime/mtime比时间戳TIME更新的文件
-amin  n:文件的atime在范围n分钟内被访问过,对这个文件运用 more、cat等命令。ls、stat命令都不会修改文件的访问时间。注意,n可以是(+ -)n,例如-amin +3表示在3分钟以前
-cmin  n:文件的ctime在范围n分钟内被修改过文件的状态,通过chmod、chown命令修改一次文件属性,这个时间就会更新
-mmin  n:文件的mtime在范围n分钟内被修改过内容,vim/vi修改保存
-atime n:文件的atime在范围24*n小时内被访问过
-ctime n:文件的ctime在范围24*n小时内被修改状态
-mtime n:文件的mtime在范围24*n小时内被修改内容
-used  n:最近一次ctime改变n天范围内,atime改变过的文件,即atime比ctime晚n天的文件,可以是(+ -)n
# find / -mtime 50
# find / -atime 50
# find / -mtime +50 –mtime -100
# find / -cmin -60
# find / -mmin -60
# find / -amin -60

2.4、actions

    actions部分一般都是执行某些命令,或实现某些功能。这部分是find的command line部分,注意,action是可以写在tests表达式前面的,它并不一定是在test表达式之后执行。

-delete         #删除文件,如果删除成功则返回true,如果删除失败,将给出错误信息。"-delete"动作隐含"-depth"-exec command;  #注意有个分号";"结尾,该action是用于执行给定的命令。如果命令的返回状态码为0则该action返回true。
                #command后面的所有内容都被当作command的参数,直到分号";"为止,其中参数部分使用字符串"{}"时,它
                #表示find找到的文件名,即在执行命令时,"{}"会被逐一替换为find到的文件名,"{}"可以出现在参数中的
                #任何位置,只要出现,它都会被文件名替换。
                #注意,分号";"需要转义,即"\;",如有需要,可以将"{}"用引号包围起来
-ok command ;   #类似于-exec,但在执行命令前会交互式进行询问,如果不同意,则不执行命令并返回false,如果同意,则执
                #行命令,但执行的命令是从/dev/null读取输入的
-print          #总是返回true。这是默认的action,输出搜索到文件的全路径名,并尾随换行符"\n"。由于在使用"-print"时所有的结
                #果都有换行符,如果直接将结果通过管道传递给管道右边的程序,应该要考虑到这一点:文件名中有空白字符(换行符、制表
                #符、空格)将会被右边程序误分解,如文件"ab c.txt"将被认为是ab和c.txt两个文件,如不想被此分解影响,可考虑使
                #用"-print0"替代"-print"将所有换行符替换为"\0"
-print0         #总是返回true。输出搜索到文件的全路径名,并尾随空字符"\0"。由于尾随的是空字符,所以管道传递给右边的程序,然后
                #只需对这个空字符进行识别分隔就能保证文件名不会因为其中的空白字符被误分解
-prune          #不进入目录,所以可用于忽略目录,但不会忽略普通文件。没有给定-depth时,总是返回true,如果给定-depth,则直接
                #返回false,所以-delete(隐含了-depth)是不能和-prune一起使用的
-ls             #总是返回true。将找到的文件以"ls -dils"的格式打印出来,其中文件的size部分以KB为单位
 a
[hive@lgh test]$ find . -type f -print -name "*.bak"  #这里有一个action -print,则会覆盖末尾默认的-print,所以在-type -f -print会把所有文件打印出来,
#然后-name "*.bak"虽然匹配到了文件,但是没有了action,所以没有操作显示 .
/3.txt ./1.bak ./3.txt ./c [hive@lgh test]$ find . -type f -print -name "*.bak" -ls #这个在上一种情况对 -name "*.bak"增加action -ls,所以会把符合条件的ls出来 ./3.bak 64356992 0 -rw-rw-r-- 1 hive hive 0 Sep 30 10:52 ./3.bak 64356990 0 -rw-rw-r-- 1 hive hive 0 Sep 30 10:52 ./1.bak 64356991 0 -rw-rw-r-- 1 hive hive 0 Sep 30 10:52 ./2.txt ./c
[hive@lgh test]$ find . -name "*.txt"
./1.txt
./3.txt
[hive@lgh test]$ find . -path  "./a" -prune -o -name "*.txt"a   #被忽略的目录也在里面
./2.txt
./3.txt

 

注意:如果find评估完所有表达式后发现没有action(-prune这个action除外),则在最末尾加上-print作为默认的action。注意,这个默认的action是在评估完所有表达式后加上的。且还需注意,如果只有-prune这个action,它还是会补上-print。

常用命令:

find /backup/rman_backup/ -mtime +45 -exec rm -rf {} ;  删除45天前的文件,这样的命令一般可以用来删除一些日志,或者一些临时文件

find /tmp -mtime +7-size +1M -exec rm -rf {} ;

find -mtime +7 -nameabc* -exec rm -rf {} ;

find /tmp -mtime +7-size +1M -ok rm -rf {} ;

 

更多linux文章请见:linux&shell学习系列

 

参考:

https://www.cnblogs.com/f-ck-need-u/p/6995529.html#auto_id_5

https://www.cnblogs.com/machangwei-8/p/10352567.html

https://blog.csdn.net/hetoto/article/details/84101745

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、信号(signal)、消息队列、共享内存、信号量、套接字(socket)。管道用于具有亲缘关系的进程间通信,有名管道的每个管道具有名字,使没有亲缘关系的进程间也可以通信。信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别对整个系统的性能做统计,而进程级别则具体到进程,为每个进程维护统计信息。&#xD;&#xA;&#xD;&#xA;按实现原理分,可分为基于计数器和跟踪以及剖析。含义如下:&#xD;&#xA;&#xD;&#xA;计数器:内核维护的统计数据,通常为无符号整型,用于对发生的事件计数,比如,网络包接收计数器,磁
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书验证,详细追踪整个交互过程,可用于调用网络后端接口,诊断http和https网络服务故障。
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满、fd泄漏等问题。命令包括ping、fping、tcpdump、lsof、netstat、/proc/$pid/fd、du、grep、traceroute、dig。
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的进程数目,用uptime查看到负载很高,既有可能是CPU利用率高,也可能是大量在等待io的进程导致,用mpstat查看每个CPU的使用情况,查看CPU的使用率或者CPU花在等待io的时间,接着用pidstat定位具体的进程
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线程切换及中断切换,进程切换的开销较大,除了需要保存寄存器和程序计数器中的值还需保存全局变量、栈等到内存中,以便下次运行恢复,而同一进程中的线程切换开销会小很多,只需更新寄存器和线程独有的栈,共享资源如打开的文件、全局变量等无需切换,当硬件中
1.top命令 作用:该命令可以按CPU使用.内存使用和执行时间对任务进行排序,常用来监控系统中占用CPU或内存较高的程序及CPU和内存的负载。 默认视图: 当想看系统负载时,可观察汇总的%CPU中的us用户进程和sy系统进程是否占用CPU很高,相加接近100%就说明占用很高了,有些程序可能得不到及
文章浏览阅读1.8k次,点赞63次,收藏54次。Linux下的目录权限!!!粘滞位!!!超详解!!!
文章浏览阅读1.6k次,点赞44次,收藏38次。关于Qt的安装、Windows、Linux、MacBook_mack book 安装qt
本文介绍了使用shell脚本编写一个 Hello
文章浏览阅读1.5k次,点赞37次,收藏43次。【Linux】初识Linux——了解操作系统的发展历史以及初次体验Linux编程环境
文章浏览阅读3k次,点赞34次,收藏156次。Linux超详细笔记,个人学习时很认真的记录的,觉得好的麻烦点个赞。
文章浏览阅读6.8k次,点赞109次,收藏114次。【Linux】 OpenSSH_9.3p1 升级到 OpenSSH_9.5p1(亲测无问题,建议收藏)_openssh_9.5p1
文章浏览阅读3.5k次,点赞93次,收藏78次。初识Linux中的线程,理解线程的各种概念,理解进程地址空间中的页表转换,介绍pthread线程库并理解线程库!
文章浏览阅读863次。出现此问题为Linux文件权限问题,解决方案为回到引擎目录执行命令。输入用户密码后运行./UnrealEditor。_increasing per-process limit of core file size to infinity.
文章浏览阅读2.9k次。使用文本编辑器:打开CSV文件,并使用文本编辑器(如Notepad++、Sublime Text、Visual Studio Code等)来查看文件的字符编码格式。通常在编辑器的底部状态栏或设置中可以找到当前编码的显示。请注意,上述方法并非绝对准确,特别是当文件没有明确的编码标识时。因此,如果你发现CSV文件在不同的工具或方法中显示不同的编码格式,可能需要进行进一步的分析和判断,或者尝试使用不同的编码转换方法。该命令将输出文件的MIME类型和编码信息。使用命令行工具:在命令行中,你可以使用。_shell读取csv文件逐行处理
本文介绍了如何在Linux系统中升级gcc版本,以便更好地支持C++11及以上版本的新特性。通过升级gcc,可以提升编译器的功能和性能,获得更好的开发体验。详细的步骤和方法请参考原文链接。
文章浏览阅读4.4k次,点赞6次,收藏19次。Mosquitto是一个开源的MQTT消息代理服务器。MQTT是一个轻量级的、基于发布/订阅模式的消息传输协议。 mosquitto的安装使用比较简单,可以方便的来进行一些测试。_linux mosquitto
文章浏览阅读7.2k次,点赞2次,收藏12次。Linux中,用于根目录下有一个.ssh目录,保存了ssh相关的key和一些记录文件。_~/.ssh/
文章浏览阅读4.5k次,点赞5次,收藏18次。首先需要安装 snmp ,使用下面的命令进行安装安装完毕之后,使用下面的命令查看是否安装成功当命令行显示如图即为安装成功。_snmp工具