find命令详解(转)

find命令详解

版权声明:

本文章内容在非商业使用前提下可无需授权任意转载、发布。

转载、发布请务必注明作者和其微博、微信公众号地址,以便读者询问问题和甄误反馈,共同进步。

微博ID:orroz

微信公众号:Linux系统技术

前言

find命令是我们日常工作中比较常用的Linux命令。全面的掌握这个命令可以使很多操作达到事半功倍的效果。如果对find命令有以下这些疑惑,本文都能帮你解决:

  1. find命令的格式是什么?
  2. 参数中出现+或-号是什么意思?比如find / -mtime +7与find / -mtime -7什么区别?
  3. find /etc/ -name “passwd” -exec echo {} \;和find /etc/ -name “passwd” -exec echo {} +有啥区别?
  4. -exec参数为什么要以“\;”结尾,而不是只写“;”?

命令基础

find命令大家都比较熟悉,反倒想讲的有特色比较困难。那干脆我们怎么平淡怎么来好了。我们一般用的find命令格式很简单,一般分成三个部分:

find /etc -name "passwd"

格式如上,第一段find命令。第二段,要搜索的路径。这一段目录可以写多个,如:

find /etc /var /usr -name "passwd"

第三段,表达式。我们例子中用的是-name “passwd”这个表达式,指定条件为找到文件名是passwd的文件。对于find命令,最需要学习的是表达式这一段。表达式决定了我们要找的文件是什么属性的文件,还可以指定一些“动作”,比如将匹配某种条件的文件删除。所以,find命令的核心就是表达式(EXPRESSION)的指定方法。

find命令中的表达式有四种类型,分别是:

  1. Tests:就是我们最常用的指定查找文件的条件。
  2. Actions:对找到的文件可以做的操作。
  3. Global options:全局属性用来限制一些查找的条件,比如常见的目录层次深度的限制。
  4. Positional options:位置属性用来指定一些查找的位置条件。

这其中最重要的就是Tests和Actions,他们是find命令的核心。另外还有可以将多个表达式连接起来的操作符,他们可以表达多个表达式之间的逻辑关系和运算优先顺序,叫做Operators。

下面我们就来分类看一下这些个分类的功能。

TESTS

find命令是通过文件属性查找文件的。所以,find表达式的tests都是文件的属性条件,比如文件的各种时间,文件权限等。很多参数中会出现指定一个数字n,一般会出现三种写法:

+n:表示大于n。

-n:表示小于n。

n:表示等于n。

根据时间查找

比较常用数字方式来指定的参数是针对时间的查找,比如-mtime n:查找文件修改时间,单位是天,就是n*24小时。举个例子说:

[[email protected] zorro]# find / -mtime 7 -ls

我们为了方便看到结果,在这个命令中使用了-ls参数,具体细节后面会详细解释。再此我们只需要知道这个参数可以将符合条件的文件的相关属性显示出来即可。那么我们就可以通过这个命令看到查找到的文件的修改时间了。

[[email protected] zorro]# find / -mtime 7 -ls|head
   524295      4 drwxr-xr-x  12  root     root         4096 6月  8 13:43 /root/.config
   524423      4 drwxr-xr-x   2  root     root         4096 6月  8 13:43 /root/.config/yelp
   524299      4 drwxr-xr-x   2  root     root         4096 6月  8 13:23 /root/.config/dconf
   524427      4 -rw-r--r--   1  root     root         3040 6月  8 13:23 /root/.config/dconf/user
...

我们会发现,时间都集中在6月8号,而今天是:

[[email protected] zorro]# date
2016年 06月 15日 星期三 14:30:09 CST

实际上,当我们在mtime后面指定的是7的时候,实际上是找到了距离现在7个24小时之前修改过的文件。如果我们在考究一下细节的话,可以使用这个命令再将找到的文件用时间排下顺序:

[[email protected] zorro]# find / -mtime 7 -exec ls -tld {} \+

此命令用到了exec参数,后面会详细说明。我们会发现,找到的文件实际上是集中在6月7日的14:30到6月8日的14:30这个范围内的。就是说,实际上,指定7天的意思是说,找到文件修改时间范围属于距离当前时间7个24小时到8个24小时之间的文件,这是不加任何+-符号的7的含义。如果是-mtime -7呢?

[[email protected] zorro]# find / -mtime -7 -exec ls -tld {} \+

你会发现找到的文件是从现在开始到7个24小时范围内的文件。但是不包括7个24小时到8个24小时的时间范围。那么-mtime +7也应该好理解了。这就是find指定时间的含义。类似的参数还有:

-ctime:以天为单位通过change time查找文件。

-atime:以天为单位通过access time查找文件。

-mmin:以分钟为单位通过modify time查找文件。

-amin:以分钟为单位通过access time查找文件。

-cmin:以分钟单位通过change time查找文件。

这些参数都是指定一个时间数字n,数字的意义跟mtime完全一样,只是时间的单位和查找的时间不一样。

除了指定时间以外,find还可以通过对比某一个文件的相关时间找到符合条件的文件,比如-anewer file。

[[email protected] zorro]# find /etc -anewer /etc/passwd

这样可以在/etc/目录下找到文件的access time比/etc/passwd的access time更新的所有文件。类似的参数还有:

-cnewer:比较文件的change time。

-newer:比较文件的modify time。

-newer还有一种特殊用法,可以用来做各种时间之间的比较。比如,我想找到文件修改时间比/etc/passwd文件的change time更新的文件:

[[email protected] zorro]# find /etc/ -newermc /etc/passwd

这个用法的原型是:find /etc/ -newerXY file。其中Y表示的是跟后面file的什么时间比较,而X表示使用查找文件什么时间进行比较。-newermc就是拿文件的modify time时间跟file的change time进行比较。X和Y可以使用的字母为:

a:文件access time。
c:文件change time。
m:文件modify time。

在某些支持记录文件的创建时间的文件系统上,可以使用B来表示文件创建时间。ext系列文件系统并不支持记录这个时间。

根据用户查找

-uid n:文件的所属用户uid为n。

-user name:文件的所属用户为name。

-gid n:文件的所属组gid为n。

-group name:所属组为name的文件。

-nogroup:没有所属组的文件。

-nouser:没有所属用户的文件。

根据权限查找

-executable:文件可执行。

-readable:文件可读。

-writable:文件可写。

-perm mode:查找权限为mode的文件,mode的写法可以是数字,也可以是ugo=rwx的方式如:

[[email protected] zorro]# find /etc/ -perm 644 -ls

这个写法跟:

[[email protected] zorro]# find /etc/ -perm u=rw,g=r,o=r -ls

是等效的。

另外要注意,mode指定的是完全符合这个权限的文件,如:

[[email protected] zorro]# find /etc/ -perm u=rw,g=r -ls
   263562      4 -rw-r-----   1  root     brlapi         33 11月 13  2015 /etc/brlapi.key

没描述的权限就相当于指定了没有这个权限。

mode还可以使用/或-作为前缀进行描述。如果指定了-mode,就表示没指定的权限是忽略的,就是说,权限中只要包涵相关权限即可。如:

[[email protected] zorro]# find /etc/ -perm 600 -ls

这是找到所有只有rw———-权限的文件,而-600就表示只要是包括了rw的其他位任意的文件。mode加/前缀表示的是,指定的权限只要某一位复合条件就可以,其他位跟-一样忽略,就是说-perm /600还可以找到r————或者-w———-这样权限的文件。老版本的/前缀是用+表示的,新版本的find意境不支持mode前加+前缀了。

根据路径查找

-name pattern:文件名为pattern指定字符串的文件。注意如果pattern中包括*等特殊符号的时候,需要加””。

-iname:name的忽略大小写版本。

-lname pattern:查找符号连接文件名为pattern的文件。

-ilname:lname的忽略大小写版本。

-path pattern:根据完整路径查找文件名为pattern的文件,如:

[[email protected] zorro]# find /etc -path "/e*d"| head
/etc/machine-id
/etc/profile.d
/etc/vnc/xstartup.old
/etc/vnc/config.d
/etc/vnc/updateid
/etc/.updated

-ipath:path的忽略大小写版本。

-regex pattern:用正则表达式匹配文件名。

-iregex:regex的忽略大小写版本。

其他状态查找

-empty:文件为空而且是一个普通文件或者目录。

-size n[cwbkMG]:指定文件长度查找文件。单位选择位:

c:字节单位。

b:块为单位,块大小为512字节,这个是默认单位。

w:以words为单位,words表示两个字节。

k:以1024字节为单位。

M:以1048576字节为单位。

G:以1073741824字节温单位。

n的数字指定也可以使用+-号作为前缀。意义跟时间类似,表示找到小于(-)指定长度的文件或者大于(+)指定长度的文件。

-inum:根据文件的inode编号查找。

-links n:根据文件连接数查找。

-samefile name:找到跟name指定的文件完全一样的文件,就是说两个文件是硬连接关系。

-type c:以文件类型查找文件:

c可以选择的类型为:

b:块设备

c:字符设备

d:目录

p:命名管道

f:普通文件

l:符号连接

s:socket

ACTIONS

表达式中的actions类型参数主要是用来对找到的文件进行操作的参数。在上面的例子中,我们已经看到可以使用-ls参数对找到的文件进行长格式显示,这就是一个actions类型的参数。类似的参数还有。

-fls file:跟-ls功能一样,区别是将信息写入file指定的文件,而不是显示在屏幕上。

-print:将找到的文件显示在屏幕上,实际上默认find命令就会将文件打印出来显示。

-print0:-print参数会将每个文件用换行分割,而这个参数适用null分割。有时候在脚本编程时可能会用上。

-fprint file:-print参数的写入文件版本。将内容写到文件中,而不是显示在屏幕上。

-fprint0 file:-print0的写入文件版本。

-delete:可以将找到的文件直接删除。

-printf:格式化输出方式打印。如:

[[email protected] zorro]# find /etc/ -name "pass*" -printf "%p "
/etc/default/passwd /etc/pam.d/passwd /etc/passwd- /etc/passwd

显示文件名,并以空格分隔。%p代表文件名。其他信息可以参见man find。

-prune:如果复合条件的是一个目录,则不进入目录进行查找。例子:

[[email protected]0 zorro]# mkdir /etc/passs
[[email protected]0 zorro]# touch /etc/passs/passwd
[[email protected]0 zorro]# find /etc/ -name "pass*" -prune
/etc/passs
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
[[email protected]0 zorro]# find /etc/ -name "pass*"
/etc/passs
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd

我们先创建了一个/etc/passs的目录,然后在这个目录下创建了一个叫passwd的文件。之后先用带-prune的find看到,能显示出passs目录,但是目录中的passwd文件并没有显示,说明这个参数让find命令没有进入这个目录查找。而后一个不带-prune参数的find显示出了passs目录下的passwd。

-quit:找到符合条件的文件后立即退出。

find中执行命令

-exec

find命令的exec是一个非常好用的参数,当然其可能造成的破坏也可能非常大。在学习它之前,我先要提醒大家,使用之前千万要确定自己在做什么。

这个参数的常见格式是:

-exec command ;

注意后面的分号。它是用来给find做标记用的。find在解析命令的时候,要区分给定的参数是要传给自己的还是要传给command命令的。所以find以分号作为要执行命令所有参数的结束标记。命令返回值为0则返回true。在exec参数指定的执行命令中,可以使用{}符号表示当前find找到的文件名。比如:

[[email protected] find]# find /etc/ -name "passwd" -exec echo {} \;
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd

上面的命令表示,找到/etc/目录下文件名为passwd的文件,并echo其文件名。注意再使用分号的时候前面要加转移字符\,因为分号也是bash的特殊字符,所以bash会先解释它。前面加上\就可以让bash直接将其船体给find命令,这个分号由find解释,而不是bash。其实这个exec用的比较废话,毕竟find本身就会找到相关条件的文件并显示其文件名。但是试想如果我们将echo换成rm或者cp,是不是就有意义的多?比如:

[[email protected] find]# find /etc/ -name "passwd" -exec rm {} \;

请不要执行这个命令!!

或者:

[[email protected] find]# find /etc/ -name "passwd" -exec cp {} {}.bak \;

这个命令可以将符合条件的文件都加个.bak后缀备份一份。于是我们可以执行删除了:

[[email protected] find]# find /etc/ -name "passwd.bak"
/etc/default/passwd.bak
/etc/pam.d/passwd.bak
/etc/passwd.bak
[[email protected] find]# find /etc/ -name "passwd.bak" -exec rm {} \;
[[email protected] find]# find /etc/ -name "passwd.bak"

当然,删除前还是要确认清楚你要删的文件一定是对的。

-execdir

execdir和exec有一些差别,主要是在执行指定的命令时,那个相关命令是在那个工作目录下执行的差别。exec是在find所指定的起始目录,而execdir是文件所在目录。对比一下就明白了:

[[email protected] find]# find /etc/ -name "passwd" -exec echo {} \;
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd
[[email protected] find]# find /etc/ -name "passwd" -execdir echo {} \;
./passwd
./passwd
./passwd

一个命令打印出来的路径都是/etc/开头,另一个显示的都是当前目录下的某某文件。

execdir的方式要比exec安全一些,因为这种执行方式避免了在解析文件名时所产生的竞争条件。

出了上述两种比较典型的执行命令的方法以外,find还对这两个参数提供了另一种形式的命令执行格式:

-exec command {} +

-execdir command {} +

我们还是先用例子来看一下这个格式和以分号结束的方式的差别:

[[email protected] find]# find /etc/ -name "passwd" -exec echo {} \;
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd
[[email protected] find]# find /etc/ -name "passwd" -exec echo {} \+
/etc/default/passwd /etc/pam.d/passwd /etc/passwd

光这样看可能还不是很明显,我们可以这样在描述一遍他们的执行过程:

echo /etc/default/passwd
echo /etc/pam.d/passwd
echo /etc/passwd

echo /etc/default/passwd /etc/pam.d/passwd /etc/passwd

其实就是说,对于command {} ;格式来说,每找到一个文件就执行一遍相关命令,而command {} +格式的意思是说,先执行find,找到所有符合条件的文件之后,将每个文件作为命令的一个参数传给命令执行,exec指定的命令实际上只被执行了一次。这样用的限制也是不言而喻的:{}只能出现一次。

[[email protected] find]# find /etc -mtime -7 -type f -exec cp -t /tmp/back/ {} \+

上面这个命令将符合条件的文件全部cp到了/tmp/back目录中,当然如果文件有重名的情况下,会被覆盖掉。从这个命令中我们学习一下{} +格式的使用注意事项,它不能写成:

find /etc -mtime -7 -type f -exec cp {} /tmp/back/ \+

所以只能使用-t参数改变cp命令的参数顺序来指定相关的动作。

无论如何,直接使用exec和execdir是很危险的,因为他们会直接对找到的文件调用相关命令,并且没有任何确认。所以我们不得不在进行相关操作前再三确认,以防止误操作。当然,find命令也给了更安全的exec参数,它们就是:

-ok

-okdir

它们的作用跟exec和execdir一样,区别只是在做任何操作之前,会让用户确认是不是ok?如:

[[email protected] find]# find /etc -mtime -7 -type f -ok cp -t /tmp/back/ {} \;
< cp ... /etc/bluetooth/main.conf > ?

于是,每一次cp你都要确认是不是要这么做。只要你输入的是y或者以y开头的任何字符串,都是确认。其他的字符串是否认。另外,这两个参数不支持{} +的格式。

OPERATORS

find的操作符(OPERATORS)实际上是用来连接多个表达式和确定其逻辑关系用的。如:

[[email protected] zorro]# find /etc -name "pass*" -type f
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd

这个find命令中使用了两个表达式,他们之间没有任何分隔,这是实际上表达的含义是,找到两个条件都符合的文件。实际上就是表达式的逻辑与关系,这跟-a参数连接或者-and参数一样:

[[email protected]0 zorro]# find /etc -name "pass*" -a -type f
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
[[email protected]0 zorro]# find /etc -name "pass*" -and -type f
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd

除了逻辑与关系以外,还有逻辑或关系:

[[email protected] zorro]# find /etc -name "pass*" -o -type f

[[email protected] zorro]# find /etc -name "pass*" -or -type f

表示两个条件只要符合其中一个都可以。

在条件表达式前面加!表示对表达式取非。同样的也可以用-not参数。另外如果表达式很多,可以使用( expr )确定优先级,如:

[[email protected] zorro]# find / \( -name "passwd" -a -type f \) -o \( -name "shadow" -a -type f \)

这里表示的是:-name “passwd” -a -type f和-name “shadow” -a -type f是或关系。

最后

find中还可能常用的其他参数比如:

-depth:制定了这个参数后,遇到目录先进入目录操作目录中的文件,最后再操作目录本身。

-maxdepth:目录最大深度限制。

-mindepth:目录最小深度限制。

还有一些其他相关参数大家可以在man find中自行补充,就不在这更多废话了。希望本篇可以对大家深入的掌握find命令有所帮助。

如果有相关问题,可以在我的微博、微信或者博客上联系我。



大家好,我是Zorro!

如果你喜欢本文,欢迎在微博上搜索“orroz”关注我,地址是:http://weibo.com/orroz

大家也可以在微信上搜索:Linux系统技术 关注我的公众号。

我的所有文章都会沉淀在我的个人博客上,地址是:http://liwei.life。

欢迎使用以上各种方式一起探讨学习,共同进步。

公众号二维码:

时间: 2024-11-08 01:57:34

find命令详解(转)的相关文章

jar打包命令详解

:如何把 java 程序编译成 .exe 文件.通常回答只有两种,一种是说,制作一个可执行的 JAR 文件包,就可以像.chm 文档一样双击运行了:而另一种回答,则是使用 JET 来进行编译.但是 JET 是要用钱买的,而且,据说 JET 也不是能把所有的 Java 程序都编译成执行文件,性能也要打些折扣.所以,使用制作可执行 JAR 文件包的方法就是最佳选择了,何况它还能保持 Java 的跨平台特性.先来看看什么是 JAR 文件包: 1. JAR 文件包 JAR 文件就是 Java Archi

Linux压缩与解压缩命令详解

简介:常用的压缩命令有gzip.bzip2.tar 提示:gzip与bzip2工具不可以对目录做打包压缩操作,gzip与bzip2解压都是用-d参数(decompress=uncompress) tar命令详解: 用法:tar 模式 [选项][路径]... 模式:    -c 创建打包文件 -delete -r --append -t --list内容 -x --extract 选项:    -C --directory -f 打包后的文件名称 -j bzip格式压缩 --remove-file

(转)Linux下PS命令详解

(转)Linux下PS命令详解 整理自:http://blog.chinaunix.net/space.php?uid=20564848&do=blog&id=74654 要对系统中进程进行监测控制,查看状态,内存,CPU的使用情况,使用命令:/bin/ps (1) ps :是显示瞬间进程的状态,并不动态连续: (2) top:如果想对进程运行时间监控,应该用 top 命令: (3) kill 用于杀死进程或者给进程发送信号: (4) 查看文章最后的man手册,可以查看ps的每项输出的含义

Linux上的free命令详解

Linux上的free命令详解 转自: http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html 解释一下Linux上free命令的输出. 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的输出看成一个二维数组FO(Free Output).例如: FO[2][1] = 24677460 FO[3][2] = 10321516 1          2          3    

Find命令详解

find命令详解 格式 find pathname -options [ -print -exec -ok ... ] 功能 在磁盘中查找文件,并作相应处理 参数 pathname         所查找的目录,可以是相对/绝对路径 options -print 将结果输出到标准输出 -exec 'command' {} \; 对结果执行该参数所给的shell命令 -ok 与-exec作用相同,不过需要用户确认是否执行命令 -name 按照文件名查找 -perm [+-]mode 按照文件权限查

iftop命令命令详解

iftop命令命令详解 作者:尹正杰 在Linux命令中有很多内置命令,和外置命令,但是内部命令的功能毕竟是有限的,比如ifconfig,它就不能看到网卡流量的 实时发送情况,尽管咱们知道可以用watch命令去查看网卡的发送接收流量的情况,但是还是不够细致,因为它仅仅能看到我们的 接受和发送的总流量,因此,我们今天来介绍一个比较好使的实施查看网络流量信息的软件---iftop,其实他的工作模式和top很像. 废话不多说~让我们直接进入正题吧: 1.想必大家都会在linux命令行上敲击ifconf

linux yum命令详解

yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载.安装.yum提供了查找.安装.删除某一个.一组甚至全部软件包的命令,而且命令简洁而又好记. yum的命令形式一般是如下:yum [options] [command] [package ...]其中的[opti

Linux上命令的使用格式和基础命令详解

一.Linux上命令的使用格式 命令行提示符详解: 用户通过终端的命令行接口来控制操作系统,登陆后如下: [[email protected] ~]# root: 当前登录的用户 @:分隔符 localhost: 当前主机的主机名,非完整格式:此处的完整格式为:localhost.localdomain [[email protected] ~]# hostname localhost.localdomain ~:用户当前所在的目录(current directory),也称为工作目录(work

scp命令详解

先说下常用的情况: 两台机器IP分别为:A.104.238.161.75,B.43.224.34.73. 在A服务器上操作,将B服务器上/home/lk/目录下所有的文件全部复制到本地的/root目录下,命令为:scp -r [email protected]:/home/lk /root. 具体过程为: [[email protected] ~]# scp -r [email protected]43.224.34.73:/home/lk /root [email protected]43.2

31个有用的系统管理员命令详解(linux)

在开始之前,你必须了解一下linux 基本知识: centos7目录结构.文件类型及权限.inode解析.信号 最常用的linux命令行快捷键.centos7 vi编辑器及环境变量的使用 Linux进程优先级及调度原理 1.Uptime 命令显示:运行时间.登陆用户数及1,5,15分钟间隔负载. # uptime 08:16:26 up 22 min,  1 user,  load average: 0.00, 0.03, 0.22 Uptime 命令仅有一个版本选项而且仅显示一天内的小时:分钟