同grep一样,这是一个shell中用法非常丰富,重要性很大的命令,所以我也用一篇文章总结一下其用法。
先用一张图片展示命令的基本语法格式:
基本、常用命令组合方式
find . -name ‘filename’
基于文件名搜索。把-name
换成-iname
,可以忽略文件名的大小写
find . -path ‘*/aireason/*’
把-name
换成 -path
,会搜索整个路径名,而不仅仅是文件名
-regex参数和-path用法类似,只不过前者用正则表达式匹配路径名;-iregex忽略文件名的大小写
find . -iregex “.*\(\.py\|\.sh\)$”
疑问:为什么要加反斜杠?
能用!
表达否定
比如find . ! -name “*.txt”
会找到所有不以txt为扩展名的文件
find默认对目录进行递归搜索,直到遍历所有制定目录下的文件和文件夹。但可以用-maxdepth 、-mindepth来限定搜索的深度
最好先制定搜索深度,再指定搜索的文件类型,这样搜索效率高
限定搜索的文件类型
-type参数来限定文件类型,有下面几种类型
普通文件 f
符号链接 l
目录 d
字符设备 c
块设备 b
套接字 s
FIFO p
与时间有关的参数 🕙
指定时间
- -atime: time of last access (ls -lu)
- -mtime: time of last modification (ls -l)
- -ctime: time of last status change (ls -lc)
-mmin, -amin,-cmin以分钟为单位,其他含义相同
三者用法类似,后面接一个整数,可以不带正负号,或者带正号、负号。下面是用法图解,间距是24h(-mtime)或一分钟(-mmin)
比如 find . -type f -mtime +3
代表查找当前目录下,访问时间在距此刻四天(4*24h)之前的所有文件
指定参考文件
另一个和时间有关的参数是-newer
,这个参数带上一个参考文件,可用于寻找比参考文件更新的(更近的修改时间)的文件。
find . -newer file.txt
,就能找到比file.txt更近时间修改的文件。
限定文件大小 📐
-size [+/-]number[k, b, c, w...]
后面接带正号或负号的整数,正好表示比数字大的文件,数字后面再接上单位,单位如下所示
🌀 b: 512 byte blocks (块,512字节)
🌀 c: Bytes (字节)
🌀 w: Two-byte words (字,两字节)
🌀 k: Kilobyte (1024 bytes)
🌀 M: Megabyte (1024 kilobytes)
🌀 G: Gigabyte (1024 megabytes)
find . -type f -name '*.pdf' -size +50000k -exec ls -l {} \;
这句话可以查找文件大于50兆的pdf文件
-delete
-delete可用来删除所匹配到的文件,比如下面命令可以删除所有以swp为扩展名的文件
find . -type f -name "*.swp" -delete
Match based on the file permissions and ownership
It is possible to match files based on the file permissions. We can list out the files having specified file permissions as follows:
find . -type f -perm 644 -print # Print files having permission 644
-perm
specifies that find should only match files with their permission set to a particular value.
As an example usage case, we can consider the case of the Apache web server. The PHP files in the web server require proper permissions to execute. We can find out the PHP files that don’t have proper execute permissions as follows:
find . -type f -name “*.php” ! -perm 644 -print
We can also search files based on ownership of the files. The files owned by a specific user can be found out using the -user USER
option.
The USER argument can be a username or UID.
For example, to print the list of all files owned by the user slynux, you can use the following command:
find . -type f -user slynux -print
使用-exec对找到的文件进行进一步操作
用法: ::-exec COMMAND {} ;::
find . -name "*.c" -exec cat {} \; > all_c.txt
解释一下,{}代表每个找到的文件,后面要用;
结尾,但是分号在shell中有特殊含义,所以需要转义。
然后,find命令的全部输出只是一个数据流,所以不需要使用>>
-exec后面不支持接多个命令,但是可以把多个命令写到脚本里,然后执行脚本。
我经常这样使用该命令:
find . -name "*.sh" -exec ls -l {} \;
让find跳过某些目录
使用-prune(修剪)参数
find . \( -name ".git" -prune \) -o \( -type f \)
此命令打印出不包括.git目录在内的所有文件,分为两部分,第一部分\( -name ".git" -prune \)
用来排除某文件夹,第二部分\( -type f \)
说明了要执行的动作
其他搜索文件的命令
Use a simpler command
Generally, source for a project is likely to be in one place, perhaps in a few subdirectories nested no more than two or three deep, so you can use a (possibly) faster command such as
cd /path/to/project; ls *.c */*.c */*/*.c
Speeding up locate
Ensure it is indexing the locations you are interested in. Read the man page and make use of whatever options are appropriate to your task.
-U <dir>
Create slocate database starting at path <dir>.
-d <path>
--database=<path> Specifies the path of databases to search in.
-l <level>
Security level. 0 turns security checks off. This will make
searchs faster. 1 turns security checks on. This is the
default.
I used the "speeding up locate" part of RedGrittyBrick's answer. I created a smaller db:
updatedb -o /home/benhsu/ben.db -U /home/benhsu/ -e "uninteresting/directory1 uninteresting/directory2"
then pointed locate
at it: locate -d /home/benhsu/ben.db