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文件夹)下所有的普通类型文件

其他参数:

-print 

将结果输出到标准输出

-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.dbmlocate.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 即可获取这篇文章进行学习; 
  • 隔一段时间强化练习一次自己认为有用但不熟的命令;可以结合“艾宾浩斯记忆曲线”进行;
  • 平时碰到需要查找文件时,刻意进行“精确”查找;时刻提醒自己不仅是要找到文件,还要记得结合文件修改时间、名称、路径、大小、权限、类型、用户及组,选择合理的搭配进行“精确”查找。