find命令是用来在给定的目录下查找符合给定条件的文件
find命令格式:
find path -option 【 -print | -ls | -delete | -fls /PATH/TO/SOMEFILE】 【 -exec | -ok command {} \; 】
find命令的参数:
1)path:要查找的目录路径。
~ 表示$HOME目录
. 表示当前目录
/ 表示根目录
2)-print:表示将结果输出到标准输出。
3)-ls:类似于对查找到的文件执行“ls -l”命令,输出文件的详细信息。
4)-delete:删除查找到的文件;
5)-fls /PATH/TO/SOMEFILE:把查找到的所有文件的长格式信息保存至指定文件中;
6)exec:对匹配的文件执行该参数所给出的shell命令。
形式为command {} \;,注意{}与\;之间有空格 ,{}花括号代表前面
find
查找出来的文件名。
7)ok:与exec作用相同,
区别在于,在执行命令之前,都会给出提示,让用户确认是否执行
8)| xargs 与exec作用相同 ,起承接作用
区别在于 | xargs 主要用于承接删除操作 ,而 -exec 都可用 如复制、移动、重命名等
9)options :表示查找方式
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 #如果遇到符号链接文件,就跟踪链接所指的文件
-empty #空的文件
-ipath p,-path p #路径名称符合 p 的文件,ipath 会忽略大小写
-prune #忽略某个目录
注意:find传递查找到的文件路径至后面的命令时,是先查找出所有符合条件的文件路径,并一次性传递给后面的命令;但是有些命令不能接受过长的参数,此时命令执行会失败;另一种方式可规避此问题:find | xargs COMMAND
下面通过一些简单的例子来介绍下find的常规用法:
1、按名字查找
find 命令中的 -name
选项可以根据文件名称进行检索(区分大小写)。如需要忽略文件名中的大小写,可以使用 -iname
选项。
-name
和 -iname
两个选项都支持 wildcards(通配符) 。如:
?
可以表示任意一个单一的符号*
可以表示任意数量(包括 0)的未知符号- [] 匹配指定字符范围内的任意单个字符
- [^] 匹配指定字符范围外的任意单个字符
注意:此处的模式匹配并不符合正则表达式。
find /usr -name '*.txt'
查找 /usr 目录下所有文件名以 .txt
结尾的文件find /usr -name '????'
查找 /usr 目录下所有文件名刚好为 4 个字符的文件
有些时候,你需要在搜索时匹配某个文件或目录的完整路径,而不仅仅是匹配文件名。可以使用 -path
或 -ipath
选项。
如查找 /usr 下所有文件名以 .txt
结尾的文件或目录,且该文件的父目录必须是 src
。可以使用以下命令:find /usr -path '*/src/*.txt'
在当前目录及子目录中,查找大写字母开头的txt文件
$ find . -name '[A-Z]*.txt' -print
在/etc及其子目录中,查找host开头的文件
$ find /etc -name 'host*' -print
在$HOME目录及其子目录中,查找所有文件
$ find ~ -name '*' -print
在当前目录及子目录中,查找不是out开头的txt文件
$ find . -name "out*" -prune -o -name "*.txt" -print
2、按目录查找
在当前目录除aa之外的子目录内搜索 txt文件
$ find . -path "./aa" -prune -o -name "*.txt" -print
在当前目录及除aa和bb之外的子目录中查找txt文件
$ find . \( −path′./dir0′ −o −path ′./dir1′ \) -a -prune -o -name '*.txt' -print
注意:在1、2处都需要加空格,否则会出现如图所示的报错
在3处加不加 -a都可以
在当前目录,不再子目录中,查找txt文件
$ find . ! -name "." -type d -prune -o -type f -name "*.txt" -print
或者 find . -name *.txt -type f -print
补充:Linux中find命令-path -prune用法详解
在Windows中可以在某些路径中查找文件,也可以设定不在某些路径中查找文件,下面用Linux中的find的命令结合其-path -prune参数来看看在Linux中怎么实现此功能。
假如在当前目录下查找文件,且当前目录下有很多文件及目录(多层目录),包括dir0、dir1和dir2 ...等目录及dir00、dir01...dir10、dir11...等子目录。
1). 在当前目录下查找所有txt后缀文件
find ./ -name *.txt
2).在当前目录下的dir0目录及子目录下查找txt后缀文件
find ./ -path './dir0*' -name *.txt
3).在当前目录下的dir0目录下的子目录dir00及其子目录下查找txt后缀文件
find ./ -path '*dir00*' -name *.txt
4).在除dir0及子目录以外的目录下查找txt后缀文件
find ./ -path './dir0*' -a -prune -o -name *.txt -print
说明:-a 应该是and的缩写,意思是逻辑运算符‘与’(&&); -o应该是or的缩写,意思是逻辑运算符‘或’(||), -not 表示非.
命令行的意思是:如果目录dir0存在(即-a左边为真),则求-prune的值,-prune 返回真,‘与’逻辑表达式为真(即-path './dir0*' -a -prune 为真),find命令将在除这个目录以外的目录下查找txt后缀文件并打印出来;如果目录dir0不存在(即-a左边为假),则不求值-prune ,‘与’逻辑表达式为假,则在当前目录下查找所有txt后缀文件。
5).在除dir0、dir1及子目录以外的目录下查找txt后缀文件
find ./ \( -path './dir0*' -o -path './dir1*' \) -a -prune -o -name *.txt -print
注意:圆括号()表示表达式的结合。即指示 shell 不对后面的字符作特殊解释,而留给 find 命令去解释其意义。由于命令行不能直接使用圆括号,所以需要用反斜杠'\'进行转意(即'\'转意字符使命令行认识圆括号)。同时注意'\(','\)'两边都需空格。
6).在dir0、dir1及子目录下查找txt后缀文件
find ./ \( -path './dir0*' -o -path './dir1*' \) -a -name *.txt -print
7). 在所有以名为dir_general的目录下查找txt后缀文件
find ./ -path '*/dir_general/*' -name *.txt -print
实例:find查找文件的时候排除某个或几个文件或目录
比如要在/usr/sam目录下查找不在dir1子目录之内的所有文件
find /usr/sam -path "/usr/sam/dir1" -prune -o -print
find [-path ..] [expression] 在路径列表的后面的是表达式
-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o -print 的简写表达式按顺序求值, -a 和 -o 都是短路求值,与 shell 的 && 和 || 类似如果 -path "/usr/sam" 为真,则求值 -prune , -prune 返回真,与逻辑表达式为真;否则不求值 -prune,与逻辑表达式为假。如果 -path "/usr/sam" -a -prune 为假,则求值 -print ,-print返回真,或逻辑表达式为真;否则不求值 -print,或逻辑表达式为假。
这个表达式组合特例可以用伪码写为
if -path "/usr/sam" then
-prune
else
-print
避开多个文件夹
find /usr/sam \( -path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -print
圆括号表示表达式的结合。
\ 表示引用,即指示 shell 不对后面的字符作特殊解释,而留给 find 命令去解释其意义。
查找某一确定文件,-name等选项加在-o 之后
#find /usr/sam \(-path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -name "temp" -print
linux下的常用命令find,加上不同的参数,可以使你很容易的找到需要的文件,但是有些时候,你在查找文件的同时,可能不需要在某文件夹下查找,这时候-prune就用上了。
比如在当前目录下寻找pl后缀的文件,不在scripts下寻找。
find . -path './scripts' -prune -o -name '*.pl' -print
3、按权限查找
find 命令可以使用 -perm
选项以文件权限为依据进行搜索。
使用符号形式
如需要检索 /usr 目录下权限为 rwxr-xr-x
的文件,可以使用以下命令:find /usr -perm u=rwx,g=rx,o=rx
搜索 /usr 目录下所有权限为 r-xr-xr-x
(即系统中的所有用户都只有读写权限)的文件和目录,可以使用以下命令:find /usr -perm a=rx
很多时候,我们只想匹配文件权限的一个子集。比如,检索可以直接被任何用户执行的文件,即只关心文件的执行权限,而不用管其读写权限是什么。
上述的需求可以通过以下命令实现:find / -type f -perm /a=x
其中 a=x
前面的 /
符号即用来表示只匹配权限的某个子集(执行权限),而不用关心其他权限的具体设置。
使用数字形式
-perm
选项也支持数字形式的文件权限标记。
find /usr -perm 644
搜索 /usr 目录下权限为 644(即 rwxr-xr-x
)的文件
在当前目录及子目录中,查找属主具有读写执行,其他具有读执行权限的文件
$ find . -perm 755 -print
查找用户有写权限或者组用户有写权限的文件或目录
find ./ -perm /220
find ./ -perm /u+w,g+w
find ./ -perm /u=w,g=w
4、按类型查找 (b/d/c/p/l/f )
如果只想搜索得到文件或目录,即不想它们同时出现在结果中。可以使用 -type
选项指定文件类型。
-type
选项最常用的参数如下:
- f: 文件
- d: 目录
- l: 符号链接
find /usr -type d -name 'python*'
检索 /usr 下所有文件名以 python
开头的目录
5、检索空文件
find 命令支持 -empty
选项用来检索为空的文件或目录。空文件即文件里没有任何内容,空目录即目录中没有任何文件或子目录。
find ~ -type d -empty
检索用户主目录下所有的空目录
在当前目录及子目录下,查找符号链接文件
$ find . -type l -print
6、反义匹配
find 命令也允许用户对当前的匹配条件进行“反义”(类似于逻辑非操作)。
如需要检索 /usr 下所有文件名不以 .txt
为后缀的文件。可以使用以下命令:find /usr -type f ! -name '*.txt'
也可以“翻转”任何其他的筛选条件,如:find /usr -type f ! -empty
检索 /usr 下所有内容不为空的文件
7、限制遍历的层数
find 命令默认是以递归的方式检索项目的,这有时候会导致得到的结果数量非常巨大。可以使用 -maxdepth
限制 find 命令递归的层数。
find / -maxdepth 3
搜索时向下递归的层数最大为 3
8、逻辑组合
在之前的例子中有出现多个搜索条件的组合以及对某个搜索条件的反转。
实际上 find 命令支持 “and” 和 “or” 两种逻辑运算,对应的命令选项分别是 -a
和 -o
。通过这两个选项可以对搜索条件进行更复杂的组合。
此外还可以使用小括号对搜索条件进行分组。注意 find
命令中的小括号常需要用单引号包裹起来。因小括号在 Shell 中有特殊的含义。
如检索 /usr 下文件名以 python
开头且类型为目录的文件find /usr -type d -name 'python*'
该命令等同于:find /usr -type d -a -name 'python*'
更复杂的组合形式如:find / '(' -mmin -5 -o -mtime +50 ')' -a -type f
参考文章:https://www.jianshu.com/p/ea8cc2248022
9、按属主及属组
查找属主是www的文件
$ find / -user www -type f -print
查找属主被删除的文件
$ find / -nouser -type f -print
查找属组 mysql 的文件
$ find / -group mysql -type f -print
查找用户组被删掉的文件
$ find / -nogroup -type f -print
10、按时间查找
查找2天内被更改过的文件
$ find . -mtime -2 -type f -print
查找2天前被更改过的文件
$ find . -mtime +2 -type f -print
查找一天内被访问的文件
$ find . -atime -1 -type f -print
查找一天前被访问的文件
$ find . -atime +1 -type f -print
查找一天内状态被改变的文件
$ find . -ctime -1 -type f -print
查找一天前状态被改变的文件
$ find . -ctime +1 -type f -print
查找10分钟以前状态被改变的文件
$ find . -cmin +10 -type f -print
11、按文件新旧
查找比 aa.txt 新的文件
$ find . -newer "aa.txt" -type f -print
查找比 aa.txt 旧的文件
$ find . ! -newer "aa.txt" -type f -print
查找比aa.txt新,比bb.txt旧的文件
$ find . -newer 'aa.txt' ! -newer 'bb.txt' -type f -print
12、按大小查找
查找超过1M的文件
$ find / -size +1M -type f -print
查找等于6字节的文件
$ find . -size 6c -print
查找小于32k的文件
$ find . -size -32k -print
13、执行命令
1)查找 del.txt 并删除,删除前提示确认
$ find . -name 'del.txt' -ok rm {} \;
2) 查找 aa.txt 并备份为aa.txt.bak
$ find . -name 'aa.txt' -exec cp {} {}.bak \;
3)查当前目录下的所有普通文件
# find . -type f -exec ls -l {} \;
-rw-r–r– 1 root root 34928 2003-02-25 ./conf/httpd.conf
-rw-r–r– 1 root root 12959 2003-02-25 ./conf/magic
-rw-r–r– 1 root root 180 2003-02-25 ./conf.d/README
查当前目录下的所有普通文件,并在 - exec 选项中使用 ls -l 命令将它们列出
4)在 /logs 目录中查找更改时间在5日以前的文件并删除它们
$ find logs -type f -mtime +5 -exec -ok rm {} \;
5)查询当天修改过的文件
# find ./ -mtime -1 -type f -exec ls -l {} \;
6)查询文件并询问是否要显示
# find ./ -mtime -1 -type f -ok ls -l {} \;
< ls … ./classDB.inc.php > ? y
-rw-r–r– 1 cnscn cnscn 13709 1月 12 12:22 ./classDB.inc.php
# find ./ -mtime -1 -type f -ok ls -l {} \;
< ls … ./classDB.inc.php > ? n
关于 有没有 -print 的区别
加 -print
查找目录并列出目录下的文件(为找到的每一个目录单独执行ls命令,没有选项-print时文件列表前一行不会显示目录名称)
find /home -type d -print -exec ls {} \;
不加 -print