Linux命令:find

命令名:find

作用: 在目录中查找文件。

说明:

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

-H, -L, -P, -D和-O 这5个参数必须在路径path的前面

  • -P:不递归所有链接对应的目录。

  • -L:递归所有链接目录。

  • -H:只递归指定的目录。(优先级高于-P和-L)

  • -D:显示debug信息(tree,stat,opt,rates,exec)

  • -O: 优化级别(0-3)

参数:


-d,-depth

在处理目录时首先处理子目录的内容,只会影响显示的结果。

-daystart

(与-atime等时间条件一起使用)表示今天的开始时间

-follow

跟踪符号链接,与-H/L/P这些特殊参数不同,可以在条件里面

-help,--help

帮助信息

-maxdepth [levels]

搜索目录的最大深度,levels为0表示一级,在-name之前

-mindepath [levels]

搜索目录的最小深度,levels为0表示所有目录

-version,--version

打印find命令的版本信息

-warn,-nowarn

打开/关闭警告信息

n参数

+n 大于n-n 小于nn 等于n

-amin [n]

在n分钟前访问过的文件

-anewer [file]

最后访问时间在文件file的修改时间之后的文件

-atime [n]

在n*24小时前访问过的文件

-cmin [n]

文件本身在n分钟前更改的文件(如chmod,chgrp,mv等)

-cnewer [file]

文件本身更改时间在文件file的修改时间之后的文件(如查找某个文件修改之后又新增的文件)

-ctime [n]

文件本身在n*24小时前更改的文件(如chmod,chgrp,mv等)

-empty

为空的文件或目录

-executable

可执行的文件或目录

-false

永远返回false

-fstype [type]

文件系统类型,不同版本unix不同

-gid [n]

组ID为n的文件

-group [gname]

组名为gname的文件,支持组ID,同-gid

-ilname [pattern]

不区分大小写匹配链接,当存在-L,-follow时,会失效。

-iname [pattern]

类似-name,不区分大小写

-inum [n]

指定inode为n的文件

-ipath [pattern]

已过时,-iwholename代替,匹配目录,不区分大小写

-iregex [pattern]

匹配全路径,不区分大小写,正则表达式

-iwholename [pattern]

匹配目录,不区分大小写

-links [n]

有n层的目录

如下d4目录结构:
$ tree  
├── d41
│   ├── d411
│   │   └── f4111
│   └── f411
├── f41
├── s11 -> ../d1/f11
└── s31 -> ../d3/f31

$find . -ipath './d4*' -links 1
./d41/f411
./d41/d411/f4111
$find . -ipath './d4*' -links 2
./d41/d411
$find . -ipath './d4*' -links 3
./d41

-mmin [n]

在n分钟前修改过的文件

-mtime [n]

在n*24小时前修改过的文件

-name [pattern]

匹配文件名pattern, 可用*号模糊匹配

-newer [file]

在文件file之后修改过的文件

-newerXY [reference]

在reference之后的文件,通过timestamp比较,其中XY是点位符,取值有:

  • a: reference的访问时间

  • B: 创建时间

  • c: inode状态改变的时间

  • m: 修改时间

  • t: reference代表一个时间


    $find . -newerat '2017-10-21 23:41:56.952710732 +0800'

-nogroup

没有所属组的文件

-nouser

没有所属用户的文件

-path [pattern]

文件路径匹配pattern的

-perm [mode]

匹配限权等于mode的文件,如6777,(6表示设置了suid,guid)


  $ll |grep zz
  -rwx------ 1 zz zz 0Oct2200:33 a
  ----rwx--- 1 zz zz 0Oct2200:33 b
  -------rwx 1 zz zz 0Oct2200:33 c
  -rw-rw-rw- 1 zz zz 0Oct2123:52 d1
  -rwxrwxr-x 1 zz zz 0Oct2121:25 f41
  lrwxrwxrwx 1 zz zz 9 Oct 21 19:21 s11 -> ../d1/f11
  lrwxrwxrwx 1 zz zz 9 Oct 21 19:21 s31 -> ../d3/f31
  $
  $find . -regex './.**' -perm 070 |xargs ls -l
  ----rwx--- 1 zz zz 0Oct2200:33 ./b

-perm -mode

u,g,o各项目权限均匹配上。


$find . -regex './.**' -perm -666 |xargs ls -l
  -rw-rw-rw- 1 zz zz 0Oct 2123:52 ./d1
  lrwxrwxrwx 1 zz zz 9Oct 2119:21 ./s11 -> ../d1/f11
  lrwxrwxrwx 1 zz zz 9Oct 2119:21 ./s31 -> ../d3/f31  

-perm +mode, /mode

u,g,o有一项权限匹配即可。


$find . -regex './.**' -perm +100 |xargs ls -l
  -rwx------ 1 zz zz 0Oct 2200:33 ./a
  -rwxrwxr-x 1 zz zz 0Oct 2121:25 ./f41
  lrwxrwxrwx 1 zz zz 9Oct 2119:21 ./s11 -> ../d1/f11
  lrwxrwxrwx 1 zz zz 9Oct 2119:21 ./s31 -> ../d3/f31

-readable

匹配可读的文件

-regex

匹配全路径,正则表达式,区分大小写

-samefile [name]

匹配和name相同inode的文件

-size n

文件大小匹配。

  • b: 512byte比特,默认单位

  • c: 字节

  • w: 双字节

  • k: 千字节(1024bytes)

  • M: 兆字节(1024*1024bytes)

  • G: G字节(1024*M)

-true

永远返回真。

-type [c]

文件类型匹配。

  • b: 块文件

  • c: 字符

  • d: 目录

  • p: 管道

  • f: 普通文件

  • l: 链接文件

  • s: socket文件

  • D: door(Solaris系统)

-uid [n]

用户id为n的文件

-used [n]

修改后在最近n天访问过的文件

-user [uname]

拥有者为uname的文件,uname可为username或uid.

-wholename [pattern]

同-path,路径匹配。选项比-path少。

-writable

可写的文件

-xtype [c]

当c为非l时,与-type一样。

当c为l时(-P,-H),-xtype不显示链接文件,-type显示链接

(-L),-xtype显示链接文件,-type不显示链接

-context [pattern]

(SELinux 开启时) 内容匹配

操作:


-delete

删除匹配的文件,删除成功返回true; 如果删除失败返回错误,但不会退出,最终find退出的返回值为非0。

使用-delete时,会自动带上-depth选项,即子目录优先处理

-exec [command] ;

执行指定的command,当command返回0时,exec返回true。

{} 用来代替文件名,在参数中任意位置使用。

exec后面全部当作参数,必须要以;结尾,部分版本的find要给;加上转义符\或用引号括起来。

exec有一定的安全性问题,建议用-execdir代替。

find . -type f -exec grep 'word' {} ';'

-exec [command] {} +

特殊的-exec命令,会将所有匹配的filename拼起来,最后一起执行。

{}只能出现一次。


d5的目录结构如下:
$tree
├── d55
│   ├── f511
│   └── f512
└── sep.txt

$cd d55
$find . -exec cat ../sep.txt {} \;   #输出多次sep.txt
=======
cat: .: Is a directory
=======
one
=======
two
$find . -exec cat ../sep.txt {} + #只输出一次
=======
cat: .: Is a directory
one
two

可以看到;和+的区别就是合并了filename

-execdir [command] ;

特殊的-exec命令,-execdir会改变当前目录,进入子目录,其它类似-exec

$find .  -exec pwd  \;                     #pwd一直是当前目录
/home/zz/test/d5
/home/zz/test/d5
/home/zz/test/d5
/home/zz/test/d5
/home/zz/test/d5
$find . -execdir pwd \;                   #pwd改变为子目录
/home/zz/test/d5
/home/zz/test/d5
/home/zz/test/d5/d55
/home/zz/test/d5/d55
/home/zz/test/d5
$find . -exec ls {} \;   #返回的文件名带父目录
d55 sep.txt
f511 f512
./d55/f511
./d55/f512
./sep.txt
$find . -execdir ls {} \;   #返回的文件名只有本身
d55 sep.txt
f511 f512
./f511
./f512
./sep.txt

-execdir [command] {} +

同-exec {} \; 与-exec {} +的区别。合并目录,只一个{}。

-fls [file]

返回true。类似-ls ,将匹配的文件名,输出到指定文件file, 以ls -lisd 命令的格式输出。

-fprint [file]

返回true。同-fls,出到到文件ls -lisd格式。

-fprint0 [file]

返回true。类似-print0,将匹配的所有文件名拼起来输出到文件file。

-fprintf [file] .[format]

返回true。类似-printf,将匹配的文件以指定格式输出到文件file。

-ls

返回true。将匹配的文件输出到终端,以ls -lisd命令的格式输出。

-ok [command]

类似-exec,每次执行command会请求用户同意,否则返回false。

-okdir [command]

类似-execdir,每次执行command会请求用户同意,否则返回false。

-print

返回true。输出文件全名到终端,一行一个。

-print0

返回true。输入文件全名到终端,拼在一起。

-printf [format]

返回true。以指定格式输出文件到终端。

  • 支持转义符(如\a\b\n\t\v等)

  • 支持文件的各项属性,以%+字母(如%a 文件最后访问时间,%p文件名,%s文件大小)

  • %A[k]:k表示时间格式(如H(00..23)小时,M(00.59)分钟)

-prune

返回true。当文件是目录时,不递归子目录匹配。遇上-depth时返回false,被忽略。不能与-delete同时用,因为-delete包含有-depth。

-quit

立即退出。不会继续往下匹配,如find /tmp/foo /tmp/bar -print -quit,只输出/tmp/foo,然后退出。

返回值由是否有错误发生决定 。

表达式


以下true/false返回值,表示是否匹配到,false即表示未匹配的文件

( expr )

优先执行,一般用\ ( ... \ ) 代替 ( ... )

! expr


#查找可执行但不可读的文件
find /sbin /usr/sbin -executable \! -readable -print


-not expr

同 ! expr,除了POSIX

expr1 expr2

与,两个表达式并列,一般当作 and 处理,expr1为false,expr2不会执行。


$ tree
├── d55
│   ├── f511
│   └── f512
└── sep.txt

$ find . -name '*2' -exec ls {} \; -a -exec rm {} \;#删除匹配的

./d55/f512
rm: remove write-protected regular file `./d55/f512'?


expr1 -a expr2

expr1 expr2

expr1 -and expr2

expr1 expr2,除了POSIX。

expr1 -o expr2

或,expr1为true,expr2不会执行。


$ find . -name '*2' -exec ls {} \; -o -exec rm {} \;#删除不匹配的

rm: remove write-protected regular file `./d55/f511'?
./d55/f512
rm: cannot remove `./d55': Is a directory
rm: remove write-protected regular file `./sep.txt'?
rm: cannot remove `.': Is a directory


expr1 -or expr2

expr1 -o expr2,除了POSIX。

expr1, expr2

同级,expr1和expr2都会执行。expr1的结果会抛弃,只返回expr2的结果。

注意:


  • 使用xargs传参时,文件名不能有空格,引号,换行等。


    $ tree
    ├── a b
    └── d55
      ├── f511
      └── f512
    $ find . -type f -name '*' -print |xargs cat

    find /tmp -name core -type f -print | xargs /bin/rm -f

    若文件名有空格,xargs截断成多个文件,则报错,文件不存在。

本博客所有文章如无特别注明均为原创。作者:zz复制或转载请以超链接形式注明转自 沉思录
原文地址《Linux命令:find

相关推荐

发表评论

路人甲 表情
Ctrl+Enter快速提交

网友评论(0)