find命令简介
1.find的作用
find是个使用频率比较高的命令。常常用它在系统特定目录下,查找具有某种特征的文件。
2. find命令的格式
find 【-path……】-options [-print –exec -ok]
path:要查找的目录路径。
~ 表示$home目录
. 表示当前目录
/ 表示根目录
print: 表示将结果输出到标准输出。
exec: 对匹配的文件执行该参数所给出的shell命令。形式为command {} \;{}与\;之间有空格。
ok :与exec作用相同,区别在于,在执行命令之前,都会给出提示,让用户确认是否执行。
3. options常用的有下选项:
-name : 按照名字查找
-perm : 按照权限查找
-prune :不再当前指定的目录下查找
-user : 文件属主来查找
-group : 文件所属组来查找
-nogroup :查找无有效属主的文件
-nouser : 查找无有效属主的文件
-type :按照文件类型查找
4.比较全的参数罗列
-amin<分钟> 查找在指定时间曾被存取过的文件或目录,单位以分钟计算。
-anewer<参考文件或目录> 查找其存取时间较指定文件或目录的存取时间更接近现在的文件或目录。
-atime<24小时数> 查找在指定时间曾被存取过的文件或目录,单位以24小时计算。
-cmin<分钟> 查找在指定时间之时被更改的文件或目录。
-cnewer<参考文件或目录> 查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录。
-ctime<24小时数> 查找在指定时间之时被更改的文件或目录,单位以24小时计算。
-daystart 从本日开始计算时间。
-depth 从指定目录下最深层的子目录开始查找。
-expty 寻找文件大小为0 Byte的文件,或目录下没有任何子目录或文件的空目录。
-exec<执行指令> 假设find指令的回传值为True,就执行该指令。
-false 将find指令的回传值皆设为False。
-fls<列表文件> 此参数的效果和指定"-ls"参数类似,但会把结果保存为指定的列表文件。
-follow 排除符号连接。
-fprint<列表文件> 此参数的效果和指定"-print"参数类似,但会把结果保存成指定的列表文件。
-fprint0<列表文件> 此参数的效果和指定"-print0"参数类似,但会把结果保存成指定的列表文件。
-fprintf<列表文件><输出格式> 此参数的效果和指定"-printf"参数类似,但会把结果保存成指定的列表文件。
-fstype<文件系统类型> 只寻找该文件系统类型下的文件或目录。
-gid<群组识别码> 查找符合指定之群组识别码的文件或目录。
-group<群组名称> 查找符合指定之群组名称的文件或目录。
-help或--help 在线帮助。
-ilname<范本样式> 此参数的效果和指定"-lname"参数类似,但忽略字符大小写的差别。
-iname<范本样式> 此参数的效果和指定"-name"参数类似,但忽略字符大小写的差别。
-inum<inode编号> 查找符合指定的inode编号的文件或目录。
-ipath<范本样式> 此参数的效果和指定"-ipath"参数类似,但忽略字符大小写的差别。
-iregex<范本样式> 此参数的效果和指定"-regexe"参数类似,但忽略字符大小写的差别。
-links<连接数目> 查找符合指定的硬连接数目的文件或目录。
-iname<范本样式> 指定字符串作为寻找符号连接的范本样式。
-ls 假设find指令的回传值为True,就将文件或目录名称列出到标准输出。
-maxdepth<目录层级> 设置最大目录层级。
-mindepth<目录层级> 设置最小目录层级。
-mmin<分钟> 查找在指定时间曾被更改过的文件或目录,单位以分钟计算。
-mount 此参数的效果和指定"-xdev"相同。
-mtime<24小时数> 查找在指定时间曾被更改过的文件或目录,单位以24小时计算。
-name<范本样式> 指定字符串作为寻找文件或目录的范本样式。
-newer<参考文件或目录> 查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录。
-nogroup 找出不属于本地主机群组识别码的文件或目录。
-noleaf 不去考虑目录至少需拥有两个硬连接存在。
-nouser 找出不属于本地主机用户识别码的文件或目录。
-ok<执行指令> 此参数的效果和指定"-exec"参数类似,但在执行指令之前会先询问用户,若回答"y"或"Y",则放弃执行指令。
-path<范本样式> 指定字符串作为寻找目录的范本样式。
-perm<权限数值> 查找符合指定的权限数值的文件或目录。
-print 假设find指令的回传值为True,就将文件或目录名称列出到标准输出。格式为每列一个名称,每个名称之前皆有"./"字符串。
-print0 假设find指令的回传值为True,就将文件或目录名称列出到标准输出。格式为全部的名称皆在同一行。
-printf<输出格式> 假设find指令的回传值为True,就将文件或目录名称列出到标准输出。格式可以自行指定。
-prune 不寻找字符串作为寻找文件或目录的范本样式。
-regex<范本样式> 指定字符串作为寻找文件或目录的范本样式。
-size<文件大小> 查找符合指定的文件大小的文件。
-true 将find指令的回传值皆设为True。
-typ<文件类型> 只寻找符合指定的文件类型的文件。
-uid<用户识别码> 查找符合指定的用户识别码的文件或目录。
-used<日数> 查找文件或目录被更改之后在指定时间曾被存取过的文件或目录,单位以日计算。
-user<拥有者名称> 查找符合指定的拥有者名称的文件或目录。
-version或--version 显示版本信息。
-xdev 将范围局限在先行的文件系统中。
-xtype<文件类型> 此参数的效果和指定"-type"参数类似,差别在于它针对符号连接检查。
2.1 find使用示例
2.1.1 find简单使用示例罗列
- 按姓名查找
[root@luodi ~]# find ~ -name "*.txt" –print 这个默认的是将家目录下面以及所有子目录下面的.txt文件查找并显示出来。
[root@luodi ~]# find . -name "[A-Z]*" –print 这个默认是将当面目录以及当前目录下面的所有子目录里面以大写字母开头的文件显示出来
[root@luodi opt]# find /etc -name "[a-z][a-z][0-9][0-9]" 这个就是将/etc目录下面的所有前两个是字母后两个是数字的文件或目录显示出来。
[root@luodi opt]# find /etc -name "[a-z][a-z][0-9][0-9]*.txt"这个是将/etc目录下面的以两个字母和两个数字开头的文件显示出来。
- 按时间查找
[root@luodi opt]# find / -amin -10 查找系统最后10分钟访问的文件或目录
[root@luodi etc]# find . -mtime -2 查找当前目录下文件2天内更改时间的文件
这里,atime代表文件的访问时间,ctime代表文件的创建时间和状态被改变的文件,mtime代表文件修改过的时间。
[root@luodi ~]# find /etc -newer zeliang ! -newer Yanshi.txt 查找更改时间比文件zeliang新但比文件Yanshi.txt旧的文件。
- 用perm权限来查找文件
[root@luodi etc]# find . -perm 755 -exec ls -l {} \; 查找当前目录下面权限为775的文件,并用ls –l 将他们罗列出来。
还有一种表达方法:在八进制数字前面要加一个横杠-,表示都匹配,如-007就相当于777,-005相当于555
- 按文件的大小来查找
[root@luodi etc]# find ~ -size +1M -exec ls -l {} \;将家目录下面大于1M的文件罗列出来。如果想将100M的查找出来就将1M改成100M。
[root@luodi etc]# find . size +1000000c –print 在当前目录下查找文件长度大于1M字节的文件。
[root@luodi etc]# find ~ -size 1660636c 查找家目录下正好长度为1660636c字节
/root/fbreader-0.12.1-requires/sqlite-3.6.21/.libs/sqlite3.o
[root@luodi etc]# find . -size +10 查找当前目录下长度超过10块的文件(一块等于512字节)
- 按文件类型查找
[root@luodi ~]# find /root -type d 查找root下类型是目录的文件
[root@luodi ~]# find /root ! -type d查找root目录下面非目录的所有文件
[root@luodi ~]# find /root -type l查找root目录下文件类型是符号链接的文件
- 按用户和用户组查找文件
[root@luodi ~]# find / -user oldboy -group oldboy -exec ls -l {} \;查找系统中用户为oldboy用户组为oldboy的文件,当然用户与用户组也可以拆开来用。
[root@luodi ~]# find / -uid 2103 查找系统中uid为2013的文件
[root@luodi ~]# find / -gid 2100 查找系统中gid为2100的文件
[root@luodi ~]# find / -not -user root 系统中非root用户的文件
[root@luodi ~]# find / -user oldboy -o -user yanshi 系统中用户为oldboy或者用户为yanshi的文件。
[root@luodi ~]# find / -nouser 查找系统中属于作废用户的文件
[root@luodi ~]# find / -false 查找系统中总是错误的文件
- 按目录层数查找
[root@luodi ~]# find / -maxdepth 2 -mindepth 1 -name "[a-z]*.txt" maxdepth表示最大层数到,mindepth表示最小层数为,这里意思就是从系统的第一层和第二层之间,其实也就是第二层查找以字母开头的txt的文件。
/mnt/blockinfo.txt 这是查找出来的结果一目了然吧都是第二层的
/etc/az19cala.txt
/root/a.txt
- 在非指定目录下查找
[root@luodi ~]# find test -path "test/test4" -prune -o –print 在test目录下面查找,但是避开test/test4子目录,内的所有文件。-prune –o –print起到了这个效果。
[root@luodi ~]# find test \( -path test/test1 -o -path test/test4 \) -prune -o –print 这是排除多个目录的用法。
find test \( -path test/test1 -o -path test/test4 \) -prune -o -name "test3" –print 这个实在排除目录的基础上,然后查找指定的名字为test3的文件
2.2 find较复杂实例讲解
- 在指定的目录下面搜索60分钟内被修改的文件,但是不显示它所属的目录。
[root@luodi ~]# find . -mmin -600 -type f 这样通过定义文件类型为普通文件就不会显示目录了。
./test/test2/test3
./test/test1/test2
./test/test4/test2
- 查找在/etc/passwd修改之后被修改过的文件,对于系统管理员来说想知道新增了一个用户后去跟踪系统的活动状态是很有帮助的(如果有新用户不老实上来乱搞的话,能很快的知道。)
[root@luodi ~]# find -newer /etc/passwd -newer
./zeliang
./test
./test/test2
- find <CONDITION to Find files> -exec <OPERATION> \;OPERATION比较常用的:
rm 命令,用于删除find查找出来的文件
mv 命令,用于重命名查找出的文件
ls -l 命令,显示查找出的文件的详细信息
md5sum, 对查找出的文件进行md5sum运算,可以获得一个字符串,用于检测文件内容的合法性
wc 命令,用于统计计算文件的单词数量,文件大小等待
执行任何Unix的shell命令
执行你自己写的shell脚本,参数就是每个查找出来的文件名
- 比如我们的系统有很多文件系统的挂载,但是我们只想在当前的挂载的文件系统上查找以.log结尾的文件,也就是不去其他的挂载点搜索。
[root@luodi ~]# find / -xdev -name "*.log" -xdev选项就是仅仅在当前的文件系统中搜索,下面是一段-xdev的定义
-xdev Don’t descend directories on other filesystems
5. 在同一个命令中使用多个{}, 将查找出来的文件备份,在文件名后面加上.bkup
[root@luodi ~]# find . -name "*.txt" -exec cp {} {}.bkup \; 首先在输入我们的操作选项的时候这个-exec是不能丢掉的,其次呢{}的多个使用只能在同一个命令中使用,在不同的命令里就不能使用多个{}了。
./tcl8.5.11/win/coffbase.txt.bkup 这里是部分输出结果
./tcl8.4.16/win/coffbase.txt.bkup
./a.txt.bkup
./Yanshi.txt.bkup
6 . 在 find结果中同时执行两条命令
[root@luodi ~]# find / \( -perm -4000 -fprint /root/suid.txt \) , \( -size +1M -fprint /root/big.txt \) 这个就是列出拥有setuid属性的文件和目录然后输出到一个/root/suid.txt的文件,然后再将文件大小超过1M的几率到/root/big.txt中
7. 显示所有的名字不是不区分大小写MYCPrRO的文件或者目录,只在当前目录下查找,并且用MD5验证和。
[root@luodi ~]# find -maxdepth 1 -type f -not -iname "MYCPrPO" -exec md5sum {} \; 首先已经指定是在当前目录而没有深入到子目录,所以最大层次也就为1层了,并且我们要将-maxdepth放到最前面,不然会有报错信息。iname呢就是不区分大小写。 在前面加上-not就是非得意思了啊。md5sum求和了解就好。
e5d2b0e06840521f18c9471819498209 ./zeliang
0dc93bc6b9bfeedf07f0564620d90eee ./yanshirm1.tar.gz
- 将两个名字相仿的文件其中一个改名,另一个例子是将相似文件带有特殊字符的文件删除。
在这里要说明一下,对于文件名称相似的文件我们最好用inode编号来查找,因为inode是唯一的所以不会搞错。
首先来说一个查找名称相似的案例,这里我们创建两个文件一个“test-name”另一个“test-name ”,是的第二个文件有空格,下面就将其中一个并改名为“new-test”
[root@luodi ~]# touch test-name 首先创建两个文件相似的文件
[root@luodi ~]# touch "test-name "
[root@luodi ~]# ls -li test-n* i就是列出文件的inode编号,列出两个文件的inode
65591 -rw-r--r-- 1 root root 0 Oct 6 13:47 test-name
65592 -rw-r--r-- 1 root root 0 Oct 6 13:47 test-name
[root@luodi ~]# find -inum 65592 -exec mv {} new-test \;这里我们将inode为65592文件查找出来然后改名为new-test。这样两个文件就容易区分了。
[root@luodi ~]# ls -li test-n*
65591 -rw-r--r-- 1 root root 0 Oct 6 13:47 test-name
[root@luodi ~]# ls -li new*
65592 -rw-r--r-- 1 root root 0 Oct 6 13:47 new-test
然后就是查找有特殊符号的文件并删除了,这里采取的方法大致是一样的。
[root@luodi ~]# touch file1.txt file2.txt file?.txt 这里我们创建了三个文件,注意看第三个它有个?符号,如果我们要删除第三个文件呢。因为?代表0或者1个任意字符啊。这样我们就只能通过inode 查找的方法来删除了。
[root@luodi ~]# ls -li file*
65593 -rw-r--r-- 1 root root 0 Oct 6 13:58 file1.txt
65594 -rw-r--r-- 1 root root 0 Oct 6 13:58 file2.txt
65595 -rw-r--r-- 1 root root 0 Oct 6 13:58 file?.txt
[root@luodi ~]# ls -li file*
65593 -rw-r--r-- 1 root root 0 Oct 6 13:58 file1.txt
65594 -rw-r--r-- 1 root root 0 Oct 6 13:58 file2.txt
10. 查找当前目录下面以及子目录中5个最大的文件,和5个最小的文件
最大的文件
[root@luodi /]# find /root -type f -exec ls -s {} \;|sort -n -r|head -5 这里sort 默认是升序排序,加-n是为了按数值排序,然后-r就是将顺序颠倒,这样我们就是按降序排序了,这样我们数值比较大的文件就输出在上面了。
[root@luodi /]# find /root -type f -exec ls -s {} \;|sort -n |tail -5 当然反转思维也行
9920 /root/.tar.gz
3744 /root/fbreader-0.12.1-requires/sqlite-3.6.21/sqlite3.c
1864 /root/tcl8.5.11/tests/clock.test
1752 /root/fbreader-0.12.1-requires/sqlite-3.6.21/test/randexpr1.test
1624 /root/fbreader-0.12.1-requires/sqlite-3.6.21/.libs/sqlite3.o最小的文件:
[root@luodi /]# find /root -type f -not -empty -exec ls -s {} \;|sort -n |head -5
这里需要注意的是,我们在查找最小文件的时候可能会遇到哪些空文件,如果我们查了半天查出了点空文件会很没有意思,所以这里加一个条件非空的普通文件,就能确保稍微的效率点。
当然find是直接对硬盘进行查找,所以在查找的过程中可能会稍微的慢一点,大家可要稍微的有点耐心的哈。如果只是对单个分区进行查找时间过长可能是语句有问题建议检查检查。