linux命令学习——find命令

138 阅读7分钟

介绍

find 是 Linux 中强大的搜索命令,不仅可以按照文件名搜索文件,还可以按照权限、大小、时间、inode 号等来搜索文件。但是 find 命令是直接在硬盘中进行搜索的,如果指定的搜索范围过大,find命令就会消耗较大的系统资源,导致服务器压力过大。所以,在使用 find 命令搜索时,不要指定过大的搜索范围。

命令格式

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]

默认路径为当前目录;默认表达式为 -print
path:要查找的目录路径。
expression参考以下说明:

EXPRESSION
       The  part of the command line after the list of starting points is the expression.  This is a kind of query specification de‐
       scribing how we match files and what we do with the files that were matched.  An expression is  composed  of  a  sequence  of
       things:

       Tests  Tests  return  a  true or false value, usually on the basis of some property of a file we are considering.  The -empty
              test for example is true only when the current file is empty.

       Actions
              Actions have side effects (such as printing something on the standard output) and return either true or false, usually
              based on whether or not they are successful.  The -print action for example prints the name of the current file on the
              standard output.

       Global options
              Global options affect the operation of tests and actions specified on any part of the command  line.   Global  options
              always return true.  The -depth option for example makes find traverse the file system in a depth-first order.

       Positional options
              Positional  options  affect  only  tests  or  actions  which follow them.  Positional options always return true.  The
              -regextype option for example is positional, specifying the regular expression dialect for regular expressions  occur‐
              ring later on the command line.

       Operators
              Operators  join  together the other items within the expression.  They include for example -o (meaning logical OR) and
              -a (meaning logical AND).  Where an operator is missing, -a is assumed.

       The -print action is performed on all files for which the whole expression is true, unless it contains an action  other  than
       -prune  or  -quit.   Actions  which  inhibit  the  default  -print  are -delete, -exec, -execdir, -ok, -okdir, -fls, -fprint,
       -fprintf, -ls, -print and -printf.

       The -delete action also acts like an option (since it implies -depth).

简答来说,就是表达式可能由下列成份一个或多个组成:操作符(operator)、选项(global options和positional options)、测试表达式(test)以及动作(actions)。其中actions是较为高级的操作

options常用选项

  • -name filename #查找名为filename的文件
  • -perm #按执行权限来查找
  • -user username #按文件属主来查找
  • -group groupname #按组来查找
  • -mtime -n +n #按文件更改时间来查找文件,-n指n天以内,+n指n天以前
  • -atime -n +n #按文件访问时间来查找文件,-n指n天以内,+n指n天以前
  • -ctime -n +n #按文件创建时间来查找文件,-n指n天以内,+n指n天以前
  • -nogroup #查无有效属组的文件,即文件的属组在/etc/groups中不存在
  • -nouser #查无有效属主的文件,即文件的属主在/etc/passwd中不存
  • -type b/d/c/p/l/f #查是块设备、目录、字符设备、管道、符号链接、普通文件
  • -size n[c] #查长度为n块[或n字节]的文件
  • -mount #查文件时不跨越文件系统mount点
  • -follow #如果遇到符号链接文件,就跟踪链接所指的文件
  • -prune #忽略某个目录

例子

按文件名查找

按文件名查找

wu@wu:~/learnshell$ find ./ -name '1.txt'
./1.txt

按文件名不分大小写

wu@wu:~/learnshell$ find ./ -iname 'abc.txt'
./Abc.txt

在在当前目录及子目录中,查找大写字母开头的txt文件

wu@wu:~/learnshell$ find . -name '[A-Z]*.txt' -print
./Abc.txt
./sub2/Bb.txt
./sub1/Aa.txt

在当前目录及子目录中,查找不是out开头的txt文件,请注意,-o选项是表示 or

wu@wu:~/learnshell$ ls
1.txt  Abc.txt  output  output2  sub1  sub2
wu@wu:~/learnshell$ find . -name 'out*' -prune -o -name '*.txt' -print
./Abc.txt
./1.txt
./sub2/bb.txt
./sub2/Bb.txt
./sub1/Aa.txt
./sub1/aa.txt

按目录查找

  1. 在当前目录除aa之外的子目录内搜索 txt文件

    wu@wu:~/learnshell$ ls -R
    .:
    1.txt  aa  Abc.txt  output  output2  sub1  sub2
    
    ./aa:
    aa.txt
    
    ./sub1:
    aa.txt  Aa.txt
    
    ./sub2:
    bb.txt  Bb.txt
    wu@wu:~/learnshell$ find . -path './aa' -prune  -o -name '*.txt' -print
    ./Abc.txt
    ./1.txt
    ./sub2/bb.txt
    ./sub2/Bb.txt
    ./sub1/Aa.txt
    ./sub1/aa.txt
    
    
  2. 在当前目录及除sub1和sub2之外的子目录中查找txt文件

    wu@wu:~/learnshell$ find . \( -path './sub1' -o -path './sub2' \)  -prune -o -name '*.txt' -print
    ./sub3/cc.txt
    ./aa/aa.txt
    ./Abc.txt
    ./1.txt
    
    
  3. 在当前目录只在sub1和sub2目录中查找txt文件

    wu@wu:~/learnshell$ ls sub3
    cc.txt
    wu@wu:~/learnshell$ find .  -path '*sub1/*.txt' -o -path '*sub2/*.txt'
    ./sub2/bb.txt
    ./sub2/Bb.txt
    ./sub1/Aa.txt
    ./sub1/aa.txt
    
  4. 在当前目录,但不在子目录查找文件

        guanwu@master:~/learnshell$ ls -R
        .:
        1.txt  aa.txt  bb.txt  sub1  sub2  sub3
    
        ./sub1:
        aa.txt  Aa.txt
    
        ./sub2:
        bb.txt  Bb.txt
    
        ./sub3:
        cc.txt
        guanwu@master:~/learnshell$ find . ! -name '*.*'  -type d  -prune -o -name '*.txt' -print
        ./aa.txt
        ./1.txt
        ./bb.txt
    

    另一种方式也可以实现只搜索当前目录的.txt文件,使用-maxdepth即可

    guanwu@master:~/learnshell$ find . -maxdepth 1 -type f -name '*.txt'
    ./aa.txt
    ./1.txt
    ./bb.txt
    

按权限查找

  • -perm 权限模式:査找文件权限刚好等于"权限模式"的文件
  • -perm -权限模式:査找文件权限全部包含"权限模式"的文件
  • -perm +权限模式:査找文件权限包含"权限模式"的任意一个权限的文件
    创建文件
   guanwu@master:~/learnshell/perm$ touch test1 test2 test3 test4
   guanwu@master:~/learnshell/perm$ chmod 755 test1
   guanwu@master:~/learnshell/perm$ chmod 444 test2
   guanwu@master:~/learnshell/perm$ chmod 600 test3
   guanwu@master:~/learnshell/perm$ chmod 200 test4
   guanwu@master:~/learnshell/perm$ ls -l
   总计 0
   -rwxr-xr-x 1 guanwu guanwu 0  1月  9 20:00 test1
   -r--r--r-- 1 guanwu guanwu 0  1月  9 20:00 test2
   -rw------- 1 guanwu guanwu 0  1月  9 20:00 test3
   --w------- 1 guanwu guanwu 0  1月  9 20:00 test4

-perm权限模式,这种搜索比较简单,代表査找的权限必须和指定的权限模式一模一样,才可以找到。

guanwu@master:~/learnshell/perm$ find . -perm 444
./test2

-perm-权限模式
如果使用"-权限模式",是代表的是文件的权限必须全部包含搜索命令指定的权限模式,才可以找到,

   guanwu@master:~/learnshell/perm$ find  . -perm -200
   .
   ./test4
   ./test1
   ./test3
   guanwu@master:~/learnshell/perm$  find . -perm -444
   .
   ./test1
   ./test2

执行 -perm -200时,./test2没有找到,这是因为/test2权限是444,没有包含200, 执行 -perm -444时,只有/test1和/test2包含444权限

-perm /权限模式 只要包含任意一个指定权限,就可以找到。

guanwu@master:~/learnshell/perm$ find . -perm /444
.
./test1
./test2
./test3

按类型查找

查找目录

 guanwu@master:~/learnshell$ find . -type d
  .
  ./sub1
  ./sub2
  ./perm
  ./sub3
  
guanwu@master:~/learnshell$ find ./ -type f
 ./sub1/aa.txt
 ./sub1/Aa.txt
 ./sub2/Bb.txt
 ./sub2/bb.txt
 ./aa.txt
 ./1.txt
 ./perm/test4
 ./perm/test1
 ./perm/test2
 ./perm/test3
 ./bb.txt
 ./sub3/cc.txt
 

测试

查找软连接

先创建软连接,再使用find . -type l命令查找

 guanwu@master:~/learnshell$ ln -s 1.txt slink-1.txt
guanwu@master:~/learnshell$ ls
1.txt  aa.txt  bb.txt  perm  slink-1.txt  sub1  sub2  sub3
guanwu@master:~/learnshell$ ls -l
总计 16
-rw-rw-r-- 1 guanwu guanwu    0  1月  9 19:43 1.txt
-rw-rw-r-- 1 guanwu guanwu    0  1月  9 19:43 aa.txt
-rw-rw-r-- 1 guanwu guanwu    0  1月  9 19:43 bb.txt
drwxrwxr-x 2 guanwu guanwu 4096  1月  9 20:00 perm
lrwxrwxrwx 1 guanwu guanwu    5  1月  9 20:36 slink-1.txt -> 1.txt
drwxrwxr-x 2 guanwu guanwu 4096  1月  9 19:43 sub1
drwxrwxr-x 2 guanwu guanwu 4096  1月  9 19:43 sub2
drwxrwxr-x 2 guanwu guanwu 4096  1月  9 19:43 sub3
guanwu@master:~/learnshell$ find . -type l
./slink-1.txt

按属主或属组

这组选项比较简单,就是按照文件的所有者和所属组来进行文件的査找

guanwu@master:~/learnshell/perm$ ls -l
总计 0
-rwxr-xr-x 1 guanwu guanwu 0  1月  9 20:00 test1
-r--r--r-- 1 guanwu guanwu 0  1月  9 20:00 test2
-rw------- 1 guanwu guanwu 0  1月  9 20:00 test3
--w------- 1 guanwu guanwu 0  1月  9 20:00 test4
guanwu@master:~/learnshell/perm$ find .  -user root
guanwu@master:~/learnshell/perm$ find . -user guanwu
.
./test4
./test1
./test2
./test3

按时间查找

Linux 中的文件有访问时间(atime)、数据修改时间(mtime)、状态修改时间(ctime)这三个时间,我们也可以按照时间来搜索文件。 命令形式

find 搜索路径 [选项] 搜索内容 选项:

  • -atime [+-]时间: 按照文件访问时间搜索
  • -mtime [+-]时间: 按照文改时间搜索
  • -ctime [+-]时间: 按照文件修改时间搜索

这三个时间的区别我们在 stat 命令中已经解释过了,这里用 mtime 数据修改时间来举例,重点说说 "[+-]"时间的含义。

  • -5:代表5天内修改的文件。
  • 5:代表前5~6天那一天修改的文件。
  • +5:代表6天前修改的文件。 请注意,也可以按照分钟来搜索,amin, mmin, cmin

查找三天内被修改的文件

guanwu@master:~/k8s/nfs$ find . -mtime -3 -type f
./flex-volume/class.yaml
./flex-volume/depolyment.yaml
./flex-volume/rbac.yaml
./flex-volume/statefulset-nfs.yaml

查找两天前被修改过的文件

guanwu@master:~/k8s/nfs$ find . -mtime +2 -type f
./staticprovisor/test-nfs-static
./staticprovisor/test-nfs-static.yaml
./staticprovisor/pvc-pod.yaml
./staticprovisor/pvc1.yaml
./staticprovisor/pv1.yaml
./hostpath.yaml
./nginx/Dockerfile
./nginx/nfs-common.deb
./test-nfs.yaml
./pv/provisor/csi/csi-nfs-controller.yaml
./pv/provisor/csi/csi-nfs-node.yaml
./pv/provisor/csi/pvc-sci.yaml
./pv/provisor/csi/rbac-csi-nfs.yaml
./pv/provisor/csi/pvc-nfs-dynamic.yaml
./pv/provisor/csi/csi-nfs-driverinfo.yaml
./pv/provisor/csi/storageClass.yaml
./pv/pvc-pod.yaml
./pv/pvc1.yaml
./pv/pv1.yaml

查找3天内被访问的文件

guanwu@master:~/k8s/nfs$ find . -atime -3 -type f
./flex-volume/class.yaml
./flex-volume/depolyment.yaml
./flex-volume/rbac.yaml
./flex-volume/statefulset-nfs.yaml
./pv/provisor/csi/csi-nfs-controller.yaml
./pv/provisor/csi/csi-nfs-node.yaml
./pv/provisor/csi/pvc-sci.yaml
./pv/provisor/csi/rbac-csi-nfs.yaml
./pv/provisor/csi/pvc-nfs-dynamic.yaml
./pv/provisor/csi/csi-nfs-driverinfo.yaml
./pv/provisor/csi/storageClass.yaml
guanwu@master:~/k8s/nfs$ 

查找一天前被访问的文件

guanwu@master:~/k8s/nfs$ find . -atime +1 -type f -print
./staticprovisor/test-nfs-static
./staticprovisor/test-nfs-static.yaml
./staticprovisor/pvc-pod.yaml
./staticprovisor/pvc1.yaml
./staticprovisor/pv1.yaml
./hostpath.yaml
./nginx/Dockerfile
./nginx/nfs-common.deb
./flex-volume/class.yaml
./flex-volume/depolyment.yaml
./flex-volume/rbac.yaml
./flex-volume/statefulset-nfs.yaml
./test-nfs.yaml
./pv/provisor/csi/csi-nfs-controller.yaml
./pv/provisor/csi/csi-nfs-node.yaml
./pv/provisor/csi/pvc-sci.yaml
./pv/provisor/csi/rbac-csi-nfs.yaml
./pv/provisor/csi/pvc-nfs-dynamic.yaml
./pv/provisor/csi/csi-nfs-driverinfo.yaml
./pv/provisor/csi/storageClass.yaml
./pv/pvc-pod.yaml
./pv/pvc1.yaml
./pv/pv1.yaml

查找三天内状态改变的文件

guanwu@master:~/k8s/nfs$ find . -ctime -3 -type f
./flex-volume/class.yaml
./flex-volume/depolyment.yaml
./flex-volume/rbac.yaml
./flex-volume/statefulset-nfs.yaml
./pv/provisor/csi/csi-nfs-controller.yaml
./pv/provisor/csi/csi-nfs-node.yaml
./pv/provisor/csi/pvc-sci.yaml
./pv/provisor/csi/rbac-csi-nfs.yaml
./pv/provisor/csi/csi-nfs-driverinfo.yaml

查找10分钟前被修改的文件

guanwu@master:~/k8s/nfs$ find . -cmin +10 -type f -print 
./staticprovisor/test-nfs-static
./staticprovisor/test-nfs-static.yaml
./staticprovisor/pvc-pod.yaml
./staticprovisor/pvc1.yaml
./staticprovisor/pv1.yaml
./hostpath.yaml
./nginx/Dockerfile
./nginx/nfs-common.deb
./flex-volume/class.yaml
./flex-volume/depolyment.yaml
./flex-volume/rbac.yaml
./flex-volume/statefulset-nfs.yaml
./test-nfs.yaml
./pv/provisor/csi/csi-nfs-controller.yaml
./pv/provisor/csi/csi-nfs-node.yaml
./pv/provisor/csi/pvc-sci.yaml
./pv/provisor/csi/rbac-csi-nfs.yaml
./pv/provisor/csi/pvc-nfs-dynamic.yaml
./pv/provisor/csi/csi-nfs-driverinfo.yaml
./pv/provisor/csi/storageClass.yaml
./pv/pvc-pod.yaml
./pv/pvc1.yaml
./pv/pv1.yaml

按新旧查找

查找比bb.txt文件更新的文件

guanwu@master:~/learnshell$ find . -newer 'bb.txt' -type f
./1.txt
./perm/test4
./perm/test1
./perm/test2
./perm/test3

查找比bb.txt旧的文件

guanwu@master:~/learnshell$ find . ! -newer  'bb.txt' -type f
./sub1/aa.txt
./sub1/Aa.txt
./sub2/Bb.txt
./sub2/bb.txt
./aa.txt
./bb.txt
./sub3/cc.txt

查找不比1.txt新,比aa.txt新的文件

guanwu@master:~/learnshell$ find . ! -newer  '1.txt' -newer 'bb.txt'  -type f
./1.txt
./perm/test4
./perm/test1
./perm/test2
./perm/test3

按大小查找

查找超过10M的文件

guanwu@master:~/jdk/jdk1.8.0_202$ find . -size +10M -type f -print
./src.zip
./jre/lib/rt.jar
./jre/lib/ext/jfxrt.jar
./jre/lib/amd64/libjfxwebkit.so
./jre/lib/amd64/server/libjvm.so
./lib/tools.jar
./lib/ct.sym
./lib/missioncontrol/plugins/com.ibm.icu_52.1.0.v201404241930.jar

查找7字节的文件

guanwu@master:~/jdk/jdk1.8.0_202$ cat 6b.txt
111111
guanwu@master:~/jdk/jdk1.8.0_202$ find . -size 7c
./6b.txt

查找小于1k的文件

guanwu@master:~/jdk/jdk1.8.0_202$ find . -size -1k -print
./jre/lib/security/trusted.libraries
./lib/visualvm/platform/.lastModified
./lib/visualvm/visualvm/config/Modules/org-netbeans-modules-uihandler.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-core-output2.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-openide-options.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-modules-core-kit.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-api-visual.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-openide-compat.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-modules-templates.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-core-execution.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-openide-execution.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-lib-uihandler.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-modules-print.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-core-io-ui.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-modules-spi-actions.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-openide-util-enumerations.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-modules-options-keymap.xml_hidden
./lib/visualvm/visualvm/config/Modules/org-netbeans-modules-favorites.xml_hidden
./lib/visualvm/visualvm/.lastModified
./lib/visualvm/profiler/.lastModified
./lib/missioncontrol/p2/org.eclipse.equinox.p2.engine/profileRegistry/JMC.profile/.lock

逻辑运算符

逻辑与 -a 查找当前目录大于20M,且为简单文件的

guanwu@master:~/jdk/jdk1.8.0_202$ find . -size +20M -a -type f
./src.zip
./jre/lib/rt.jar
./jre/lib/amd64/libjfxwebkit.so

三天之内修改过,且文件类型为symbolic的

guanwu@master:~/learnshell$ find . -mtime -3 -a -type l
./slink-1.txt

执行命令-exec

查找当天有修改的文件

guanwu@master:~/learnshell$ find   ./   -mtime   -1   -type f   -exec   ls -l   {} \;
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 19:43 ./sub1/aa.txt
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 19:43 ./sub1/Aa.txt
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 19:43 ./sub2/Bb.txt
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 19:43 ./sub2/bb.txt
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 19:43 ./aa.txt
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 20:38 ./1.txt
--w------- 1 guanwu guanwu 0  1月  9 20:00 ./perm/test4
-rwxr-xr-x 1 guanwu guanwu 0  1月  9 20:00 ./perm/test1
-r--r--r-- 1 guanwu guanwu 0  1月  9 20:00 ./perm/test2
-rw------- 1 guanwu guanwu 0  1月  9 20:00 ./perm/test3
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 19:43 ./bb.txt
-rw-rw-r-- 1 guanwu guanwu 0  1月  9 19:43 ./sub3/cc.txt

查找今天内有修改的文件,并重定向当天日期到找到的文件中

guanwu@master:~/learnshell/test2$ ls
1.txt  2.txt  3.txt
guanwu@master:~/learnshell/test2$ find ./  -name '*.txt' -exec bash -c 'echo "$(date) " > $(basename $0)' {} \;
guanwu@master:~/learnshell/test2$ cat *.txt
2024年 01月 09日 星期二 21:27:56 CST 
2024年 01月 09日 星期二 21:27:56 CST 
2024年 01月 09日 星期二 21:27:56 CST 
guanwu@master:~/learnshell/test2$ find ./  -name '*.txt' -exec bash -c 'echo "$(date) " > $(basename $0)' {} \;
guanwu@master:~/learnshell/test2$ cat *.txt
2024年 01月 09日 星期二 21:28:54 CST 
2024年 01月 09日 星期二 21:28:54 CST 
2024年 01月 09日 星期二 21:28:54 CST 

查询文件询问是否需要显示

guanwu@master:~/learnshell/test2$ find ./ -mtime -1 -type f -ok ls -l {} \; 
< ls ... ./1.txt > ? y
-rw-rw-r-- 1 guanwu guanwu 44  1月  9 21:28 ./1.txt
< ls ... ./3.txt > ? y
-rw-rw-r-- 1 guanwu guanwu 44  1月  9 21:28 ./3.txt
< ls ... ./2.txt > ? y
-rw-rw-r-- 1 guanwu guanwu 44  1月  9 21:28 ./2.txt

参考

c.biancheng.net/view/779.ht…
blog.csdn.net/l_liangkk/a…