linux下文件查找命令用法总结。
前言
我们经常需要在linux系统中查找一个文件,或需要知道哪些文件包含已知的特有信息,便于快速对比排查、分析问题,那么如何准确高效查找呢?
其实在linux下可查找文件的命令不止一个,命令附带的用法也不止一个,有些组合功能真的很强大,尤其是find命令。如果你目前查找文件,使用最多的命令仅是 find ./ -name "test"
,那这篇最全最详也许没有之一的
文章绝对值得一读,必有收获。
建议:
关注 并 星标 公众号 嵌入式er笔记 ,后续干货可以及时看到。
阅前Tips:
linux下一切皆文件;
* 表示通配任意字符及组合;
? 表示通配任意的单个字符;
[] 表示通配括号[]里面的任意一个字符;
"" 注意是英文字符的引号,一定不要搞错;
命令行、表格文本,屏幕宽度所限可能看不全,右滑即可;
1. find命令
find命令尝个鲜
如:
find ./ -name "*.doc" -a -user kobe
意为,查找用户kobe
在当前目录下的所有.doc
文件
再如:
find ./ -name "*.doc" -type f -a -user kobe -exec grep -ri "mvp" {} \; -print
相信认真读完这篇文章,理解这条查找语句就不在话下了。
find命令格式
find命令一般格式:
find path -option -print
find命令结合-exec/-ok
使用格式:
find path -option [-exec/-ok command {} \; ] [-print]
find命令结合xargs
使用格式:
find path -option [-print] [|xargs command]
find命令详细
格式参数 | 说明/实例 |
---|---|
path | 要查找的目录/路径,多个路径可以空格隔开 |
“~” | 在$HOME目录查找,如 find ~ -name “test”,有时为了排查不同的$HOME目录配置差异会用到 |
“/” | 在系统根目录查找,如 find / -name “test”,系统根目录为基准文件和目录众多肯定是非常慢的,不常用 |
“.”或“’./’” | 在当前目录查找,如 find ./ -name “test”,平常使用应该最多,当前目录寻找文件或者目录是常有之事 |
同时多个路径/目录一起查找,如 find /usr /home /etc -name kobe,在/usr /home /etc查找所有以kobe命名的文件 | |
-option | -option 可以是以下(1)(2)(3)…… |
(1)指定文件名 | 指定文件名称查找,可以结合通配符更好的使用 |
-iname | 如 find ./ -iname “*linux.doc”,在当前目录查找以“linux.doc”结尾的文件,文件名不区分大小写 |
-name | 如 find ./ -name “*linux.doc”,在当前目录查找以“linux.doc”结尾的文件,文件名区分大小写 |
如 find ./ -name “[A-Z]*”,在当前目录及子目录中查找文件名以一个大写字母开头的文件 | |
如 find ./ -name “[a-z]*[0-9].doc”,在当前目录查找文件名以一个小写字母开头,最后是0到9命名的.doc的文件 | |
如 find ./ -name “A?a.doc”,在当前目录查找文件名以一个大写字母A开头,中间是任意一个字符,最后以一个小写字母a结尾的.doc文件,也就是.doc文件名称只有三个字符,前后两个限定为A和a,中间一个随意 | |
(2)指定用户及组 | 结合用户及组查找 |
-user | 根据属主来查找文件,如 find ./ -user kobe,查找文件所属用户为 kobe 的所有文件 |
-group | 根据属组来查找文件,如 find ./ -group kobe,查找文件所属组为 kobe 的所有文件 |
-nouser | 如 find ./ -type f -nouser,查询没有所属用户的文件,查找文件的拥有者不在/etc/passwd中 |
-nogroup | 如 find ./ -type f -nogroup,查询没有所属组的文件,查找文件的用户组不在/etc/group中 |
(3)指定文件类型 | 结合/指定文件类型查找 |
-type f | 查找普通类型文件,如 find ./ -type f -name ‘*test’,查找名字包含test的文件 |
-type d | 查找目录directory类型文件(一切皆文件,目录本身也是一种文件),如 find ./ -type d -name ‘*test’,查找名字包含test的目录 |
-type c | 查找字符设备文件,如 find ./ -type c -name ‘*test’,查找名字包含test的字符设备文件 |
-type b | 查找块设备文件,如 find ./ -type b -name ‘*test’,查找当前名字包含test的块设备文件 |
-type l | 查找链接文件,如 find ./ -type l -name ‘*test’,查找名字包含test的链接文件 |
-type p | 查找管道文件,如 find ./ -type p -name ‘*test’,查找名字包含test的管道文件 |
(4)指定大小 | 根据文件大小查询,数字n后面如果跟 c 表示以bytes为单位,还可以跟M,G等, |
-size -n | 查找小于 大小为 n 的文件,如 find ./ -size -1024M,查找小于1024M的文件 |
-size +n | 查找大于 大小为 n的文件,如 find ./ -size +1024M,查找大于1024M的文件 |
(5)指定时间 | 根据时间查询 |
按天查询 | 可以是-ctime或-atime或-mtime,这里以-mtime为例 |
mtime:文件内容被修改的最后时间; atime:文件中的数据库最后被访问的时间; ctime:文件的元数据发生变化,比如权限,所有者等; | |
-mtime -n | 查询在n天以内被修改过的文件,如 find ./ -name “test” -mtime -20 find ./ -mtime -2 -a -name ‘test*’ |
-mtime +n | 查询在n天以外被修改过的文件,如 find ./ -name “test” -mtime +2 |
-mtime n | 查询正好在n天(一天之内)被修改过的文件,如 find ./ -name “test” -mtime 2 |
按分钟查询 | 可以是-cmin或-amin或-mmin,含义可类比按天查询,这里以-mmin为例 |
-mmin -n | 查询在n分钟以内修改过的文件,如 find ./ -mmin -20 -type d,查找在20分钟以内修改过的目录 |
-mmin +n | 查询在n分钟之前修改过的文件,如find ./ -mmin +20 -type d,查找在20分钟以前修改过的目录 |
(6)指定权限 | -perm,根据权限查找文件 |
-perm mode | 查找文件权限刚好符合mode的文件,如 find ./ -perm 666,查找文件属主和组及其他用户权限都为可读,可写的文件 |
还可以搭配-mode 或+mode用,但我觉得太绕了,学习和记忆成本太大,对于开发人员平时使用来说,采用-perm mode方式,查找直接,正常也就足够了 | |
(7)指定路径 | 注意这里的路径是-option,是固定的关键字搭配,方便更精确的查找对应路径文件 |
-path | 查找路径名称符合 p 的文件,注意p需引号引起来,如 find ./ -path “*git*/config”,查找所有git路径下的config文件 |
-ipath | 用法同上,区别就是,-ipath 路径不区分大小写,即大写路径、小写路径都查找 |
-prune | 通常和 -path 一起使用,用于将特定目录排除在搜索条件之外,过滤条件写在其他条件前面 |
如 find ./mywork -path “./mywork/kobe” -prune -o -type f,意为在mywork目录下查找不在kobe子目录内的所有普通文件,所以-prune可以帮助我们避开某个目录,然后进行查找 | |
如 find ./mywork \( -path ./mywork/kobe -o -path ./mywork/james \) -prune -o -type f,意为在mywork目录下查找不在(kobe或james)子目录内的所有普通文件,所以通过-prune也可以帮助我们避开多个目录,然后进行查找;说明:命令中( )作用是表达式的结合; \作用是告诉 shell 不要对其后挨着的括号字符作特殊解释,留着本意给 find 命令去使用,必须要记得用”\”来转义 | |
如 find ./mywork \( -path ./mywork/kobe -o -path ./mywork/james \) -prune -o -iname “*mvp” -print,避开以上多个目录,查找名称以mvp结尾的文件,不区分大小写 | |
(8)指定查找逻辑 | 支持 与 、或、非 查找,默认啥都不带的情况下,查询条件之间都是 与 的关系 |
-a | 与,查找连接的两个条件必须同时满足的文件;如 find ./ -name “*.doc” -a -user kobe,查找用户kobe在当前目录下的所有.doc文件 |
-o | 或,查找连接的两个条件满足其一即可的文件;如 find ./ -nogroup -o -nouser,查找没有属主或者没有属组的文件,系统安全考虑,可能需要在特定路径下,经常这样查找review看下没有归属的可疑文件,及时排查风险;再如上面搭配-prune使用的例子,find ./mywork -path “./mywork/kobe” -prune -o -type f,在mywork目录下查找不在kobe子目录内的所有普通文件 |
再如上面搭配-prune使用的例子,find ./mywork -path “./mywork/kobe” -prune -o -type f,是按从左到右顺序查找求值,-o的作用就是保证在排除kobe子目录后能继续查找列出其他满足-type f的文件 | |
-not 或 ! | 非,查找排除了紧跟连接条件的文件;如 find ./ -type f ! -path “*/.git/*”,查找当前目录(除了git文件夹)下所有的普通类型文件 |
其他参数: | |
将结果输出到标准输出 | |
-exec {} \; | 对匹配的文件执行该参数所给出的shell命令cmd;形式为 cmd{} \;,注意 {} 与 \; 之间有空格 ;因为”;” 在部分shell环境下是有特殊意义,所以必须要记得用”\”来转义 |
-ok {} \; | 与-exec作用相同,区别在于-ok在执行命令之前,都会给出提示,让用户确认是否执行 |
| xargs | 通过管道命令 | 将左侧命令的标准输出转换为标准输入,提供给右侧 xargs,而xargs的作用就是将传递过来的标准输入转为cmd参数使用;cmd可以是grep、ls、rm等等shell可以解析的命令 |
结合参数| xargs、-exec、-ok、-print 使用举栗:
find
和|xargs
组合使用:
比如我拉下来一套干净代码,不干别的,仅为了看代码而已,空闲时间就可以采用如下命令,将碍眼IDE的.git相关全部删除:
root@ubuntu:~$ find ./ -name ".git*" |xargs rm -rf
以上,等同于如下
find
和-exec
组合使用:
root@ubuntu:~$ find ./ -name ".git*" -exec rm -rf {} \;
还可以在删除的时候,和命令
-ok
组合使用,增加提示让用户确认(y执行,n不执行):
root@ubuntu:~$ find ./ -name ".git*" -ok rm -rf {} \; < rm ... ./.git > ? y < rm ... ./.git1 > ? y < rm ... ./.git2 > ? y < rm ... ./.git3 > ? y
最后看下
-print
使用效果:
比如我想快速查找和查看一下,在当前目录下归属于kobe这个用户的所有.doc文件,包含“mvp”关键字的信息情况;就可以用到前面尝鲜的例子;
带 -print
的效果:
root@ubuntu:~$ find ./ -name "*.doc" -type f -a -user kobe -exec grep -ri "mvp" {} \; -print Kobe Bryant will be regular season and Finals MVP at that point. ./RIP.doc I am also the MVP of our village. ./BLACK8.doc
不带 -print
的效果:
root@ubuntu:~$ find ./ -name "*.doc" -type f -a -user kobe -exec grep -ri "mvp" {} \; Kobe Bryant will be regular season and Finals MVP at that point. I am also the MVP of our village.
可以看到,带 -print
会打印出更多有用信息,不仅有grep到的mvp信息,还有对应的文件信息。
2. locate命令
安装和配置:
locate
命令一般非linux系统自带,比如在ubuntu下就需要手动安装才能使用;需要执行sudo apt-get install mlocate
;和
find
比较:find
命令查找相当于直接在文件系统里面找硬盘上的东西,而locate
是有属于自己的一个数据库mlocate.db
,比我在ubuntu里面安装后默认在/var/lib/mlocate/mlocate.db
;mlocate.db
是不断更新和维护存储的文件索引,每次locate
查找时都是在mlocate.db
里面查找索引,并不会真的在文件系统里找硬盘上的东西,所以locate
查找速度要比find
快;也正因为这样,只有数据库mlocate.db
里存在索引的文件才能被找到,虽然系统每天会自动更新数据库,但是当下实时的一些文件变动,必须要我们手动更新数据库后才行;万一忘了更新,就会查找不到,查找结果就会不准确;可以通过命令
sudo updatedb
手动更新数据库mlocate.db
;locate命令格式:
locate [OPTION]... [PATTERN]...
locate常用命令:
OPTION | 说明/实例 |
---|---|
如 locate .git/*config* ,查找.git目录下所有名称含有config的文件或目录(星号为通配符) | |
如 locate mvp,查找所有名称包含mvp的文件或目录 | |
-i | 不区分大小写进行查找,如 locate –i mvp,查找所有名称包含mvp的文件或目录,不区分大小写 |
-c | 统计查找到的条目个数,如 locate –c mvp,查找看有多少个文件或目录名称包含mvp |
更多使用方法,可以 locate --help
获取,如:
root@ubuntu:~$ locate --help -A, --all only print entries that match all patterns -b, --basename match only the base name of path names -c, --count only print number of found entries -d, --database DBPATH use DBPATH instead of default database (which is /var/lib/mlocate/mlocate.db) //可以自行指定数据库 -e, --existing only print entries for currently existing files -L, --follow follow trailing symbolic links when checking file existence (default) -h, --help print this help -i, --ignore-case ignore case distinctions when matching patterns //忽略大小写 -p, --ignore-spaces ignore punctuation and spaces when matching patterns -t, --transliterate ignore accents using iconv transliteration when matching patterns -l, --limit, -n LIMIT limit output (or counting) to LIMIT entries -m, --mmap ignored, for backward compatibility -P, --nofollow, -H don't follow trailing symbolic links when checking file existence -0, --null separate entries with NUL on output -S, --statistics don't search for entries, print statistics about each used database -q, --quiet report no error messages about reading databases //不会显示任何错误错误讯息 -r, --regexp REGEXP search for basic regexp REGEXP instead of patterns //使用基本正则表达式 --regex patterns are extended regexps //使用扩展正则表达式 -s, --stdio ignored, for backward compatibility -V, --version print version information -w, --wholename match whole path name (default)
3. which命令
如果你要查找的是系统中的可执行文件,就可以考虑用which
命令;
which
是通过$PATH
环境变量,查找该变量指定路径内的可执行文件;需要注意,假如被查找的可执行文件没有被添加到$PATH
,是无法被which
到的;基本上ubuntu通过apt-get install安装过的可执行命令(即一种可执行文件)都默认会被添加到
$PATH
了,假如真的有些没有被添加到,安装完成后,需要我们手动添加一下;可套用如下命令格式(路径/mytools/bin可根据实际情况进行替换):
export PATH="$PATH:/mytools/bin"
另外,也可以结合需要,将这条命令直接修改进 系统
profile
文件 或 当前用户.bashrc
文件;注意,如果是修改进文件需要重新注销/登录一次才能生效,可以通过
echo $PATH
查看确认;which常用命令:
参数 | 说明/实例 |
---|---|
如 which ls,which默认返回在$PATH中搜索到的第一个结果 | |
如 which which,查找which命令自己的位置 | |
如 which ls file,一次查找多个(ls 和 file)命令的位置 | |
-a | 如 which –a ls,查找在$PATH中所有ls的位置;which默认返回在$PATH中搜索到的第一个结果,如果想查看所有搜索结果,可以使用参数-a |
更多使用方法,可以 which --help
获取。
4. whereis命令
whereis
命令可以用来查找系统中的二进制文件(如系统命令文件)、源代码文件、帮助手册(man)文件;
查询目录说明
一般包含二进制文件的目录有:/sbin,/bin,/usr/bin,/usr/lib
一般包含源代码文件的目录有:/usr/src
一般包含手册文件的目录有:/usr/local/man,/usr/share/man
和
which
比较whereis
不仅可查找系统中的可执行文件(二进制文件),还可以查找源代码文件、帮助手册(man)文件,覆盖面比which
要广一些;whereis
命令是通过文件索引数据库查找的(这点类似locate),而which
依靠$PATH
查找;注意&疑问:因为采用数据库的方式并不是实时更新,所以,我们在用whereis和locate 查找文件时,有时可能会看到已经被清理的文件被查找到,或者 实时变动的文件无法被查找到。对于locate可以手动更新数据库前面已经介绍,但是一直没有找到如何手动更新whereis数据库的方法,可能主要依赖系统吧,如果你知道其更新原理或者如何更新,还请帮忙告知,我补充在后续文章中,感谢。
whereis常用命令:
参数 | 说明/实例 |
---|---|
-b | 查找二进制文件,如 whereis -b ls,指定要查找的是二进制可执行命令ls文件位置 |
-m | 查找说明手册manual路径下的文件,如whereis -m svn,如果安装的svn带有对应的manual指导手册,就会被快速查找出来 |
-s | 查找source源文件,如 whereis -m svn,如果安装的svn带有源码,就会包快速查找到 |
更多使用方法,可以 whereis --help
获取。
5. Ps.End
这么多命令和参数,记不住、使用不熟怎么办,没关系,千万不要心急,命令想熟练使用一定需要刻意训练和长期使用积累才行,一口吃不成大胖子 说点个人建议吧:
可以先将文章当做一个随时可查询的手册对待,可 关注 并 星标 公众号 嵌入式er笔记,后续随时在对话框,发送
find
即可获取这篇文章进行学习;隔一段时间强化练习一次自己认为有用但不熟的命令;可以结合“艾宾浩斯记忆曲线”进行;
平时碰到需要查找文件时,刻意进行“精确”查找;时刻提醒自己不仅是要找到文件,还要记得结合文件修改时间、名称、路径、大小、权限、类型、用户及组,选择合理的搭配进行“精确”查找。
如果觉得文章有用,帮忙动动手指
点赞、在看,给作者点鼓励持续写作和分享
往期文章
>专辑 | C/C++细碎
>专辑 | 磨刀不误砍柴工
>文章 | 程序员不应该就是专职敲代码的吗
>文章 | 手机屏幕封装技术及其分类相关知识
>文章 | 大端小端详解(含代码及详细注释)
>文章 | 你真的了解开源吗
>文章 | 浅谈ARM ABI,Android ABI
>文章 | CPU、ARM、架构(及指令集)关系
>文章 | 我毕业了(来自小学妹的毕业随笔)
如果觉得文章有用,帮忙动动手指
点赞、在看,给作者点鼓励持续写作和分享