首页 > 代码库 > Linux 文件查找

Linux 文件查找

在Linux系统的查找相关的命令:

  • which 查看可执行文件的位置

  • whereis 查看文件的位置

  • locate 配合数据库查看文件位置

  • find 实际搜寻硬盘查询文件名称

whereis

whereis命令是定位可执行文件、源代码文件、帮助文件在文件系统中的位置。这些文件的属性应属于原始代码,二进制文件,或是帮助文件。whereis 程序还具有搜索源代码、指定备用搜索路径和搜索不寻常项的能力。

语法

whereis [-bmsu] 文件或者目录名称

参数

  • -b 定位可执行文件。

  • -m 定位帮助文件。

  • -s 定位源代码文件。

  • -u 搜索默认路径下除可执行文件、源代码文件、帮助文件以外的其它文件。

  • -B 指定搜索可执行文件的路径。

  • -M 指定搜索帮助文件的路径。

  • -S 指定搜索源代码文件的路径。

举例

将和passwd文件相关的文件都查找出来:

[root@hpf-linux ~]# whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz

只将二进制文件 查找出来 :

[root@hpf-linux ~]# whereis -b passwd
passwd: /usr/bin/passwd /etc/passwd

和find相比,whereis查找的速度非常快,这是因为linux系统会将 系统内的所有文件都记录在一个数据库文件中,当使用whereis和下面即将介绍的locate时,会从数据库中查找数据,而不是像find命令那样,通 过遍历硬盘来查找,效率自然会很高。 但是该数据库文件并不是实时更新,默认情况下时一星期更新一次,因此,我们在用whereis和locate 查找文件时,有时会找到已经被删除的数据,或者刚刚建立文件,却无法查找到,原因就是因为数据库文件没有被更新。

which

which命令的作用是,在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。也就是说,使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令。

参数

  • -n  指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名。

  • -p  与-n参数相同,但此处的包括了文件的路径。

  • -w  指定输出时栏位的宽度。

  • -V  显示版本信息

locate

locate命令可以在搜寻数据库时快速找到档案,数据库由updatedb程序来更新,updatedb是由cron daemon周期性建立的,locate命令在搜寻数据库时比由整个由硬盘资料来搜寻资料来得快,但较差劲的是locate所找到的档案若是最近才建立或刚更名的,可能会找不到,在内定值中,updatedb每天会跑一次,可以由修改crontab来更新设定值。由于linux系统没有默认安装locate命令,所以需要手动安装:yum -y install mlocate。
locate指定用在搜寻符合条件的档案,它会去储存档案与目录名称的数据库内,寻找合乎范本样式条件的档案或目录录,可以使用特殊字元(如”*” 或”?”等)来指定范本样式,如指定范本为kcpa*ner, locate会找出所有起始字串为kcpa且结尾为ner的档案或目录,如名称为kcpartner若目录录名称为kcpa_ner则会列出该目录下包括 子目录在内的所有档案。
locate指令和find找寻档案的功能类似,但locate是透过updatedb程序将硬盘中的所有档案和目录资料先建立一个索引数据库,在 执行loacte时直接找该索引,查询速度会较快,索引数据库一般是由操作系统管理,但也可以直接下达updatedb强迫系统立即修改索引数据库。

参数

  • -e 将排除在寻找的范围之外。

  • -1 如果 是 1.则启动安全模式。在安全模式下,使用者不会看到权限无法看到 的档案。这会始速度减慢,因为 locate 必须至实际的档案系统中取得档案的 权限资料。

  • -f 将特定的档案系统排除在外,例如我们没有到理要把 proc 档案系统中的档案 放在资料库中。

  • -q 安静模式,不会显示任何错误讯息。

  • -n 至多显示 n个输出。

  • -r 使用正规运算式 做寻找的条件。

  • -o 指定资料库存的名称。

  • -d 指定资料库的路径

  • -h 显示辅助讯息

  • -V 显示程式的版本讯息

find

每一种操作系统都是由成千上万个不同种类的文件所组成的。其中有系统本身自带的文件,用户自己的文件,还有共享文件等等。我们有时候经常忘记某份文件放在硬盘中的哪个地方。在微软的WINDOWS操作系统中要查找一份文件是相当简单的事情,只要在桌面上点击“开始”-“搜索”中就能按照各种方式在本地硬盘上,局域网络,甚至在INTERNET上查找各种文件,文档。
可是使用Linux的用户就没有那么幸运了,在Linux上查找某个文件确实是一件比较麻烦的事情。毕竟在Linux中需要我们使用专用的“查找”命令来寻找在硬盘上的文件。Linux下的文件表达格式非常复杂,不象WINDOWS,DOS下都是统一的AAAAAAA.BBB格式那么方便查找,在WINDOWS中,只要知道要查找的文件的文件名或者后缀就非常容易查找到。Linux中查找文件的命令通常为“find”命令,“find”命令能帮助我们在使用,管理Linux的日常事务中方便的查找出我们需要的文件。

用法

find [OPTIONS]  [查找起始路径]  [查找条件]  [处理动作]

查找起始路径:指定具体搜索目标起始路径;默认为当前目录;
查找条件:指定的查找标准,可以根据文件名、大小、类型、从属关系、权限等等标准进行;默认为找出指定路径下的所有文件;
处理动作:对符合查找条件的文件做出的操作,例如删除等操作;默认为输出至标准输出;

命令选项

  • -amin<分钟>:查找在指定时间曾被存取过的文件或目录,单位以分钟计算;

  • -atime<24小时数>:查找在指定时间曾被存取过的文件或目录,单位以24小时计算;

  • -cmin<分钟>:查找在指定时间之时被更改过的文件或目录;

  • -ctime<24小时数>:查找在指定时间之时被更改的文件或目录,单位以24小时计算;

  • -depth:从指定目录下最深层的子目录开始查找;

  • -exec<执行指令>:假设find指令的回传值为True,就执行该指令;

  • -false:将find指令的回传值皆设为False;

  • -fls<列表文件>:此参数的效果和指定“-ls”参数类似,但会把结果保存为指定的列表文件;

  • -follow:排除符号连接;

  • -fprint<列表文件>:此参数的效果和指定“-print”参数类似,但会把结果保存成指定的列表文件;

  • -fprint0<列表文件>:此参数的效果和指定“-print0”参数类似,但会把结果保存成指定的列表文件;

  • -fprintf<列表文件><输出格式>:此参数的效果和指定“-printf”参数类似,但会把结果保存成指定的列表文件;

  • -fstype<文件系统类型>:只寻找该文件系统类型下的文件或目录;

  • -gid<群组识别码>:查找符合指定之群组识别码的文件或目录;

  • -group<群组名称>:查找符合指定之群组名称的文件或目录;

  • -ilname<范本样式>:此参数的效果和指定“-lname”参数类似,但忽略字符大小写的差别;

  • -iname<范本样式>:此参数的效果和指定“-name”参数类似,但忽略字符大小写的差别;

  • -inum:查找符合指定的inode编号的文件或目录;

  • -ipath<范本样式>:此参数的效果和指定“-path”参数类似,但忽略字符大小写的差别;

  • -iregex<范本样式>:此参数的效果和指定“-regexe”参数类似,但忽略字符大小写的差别;

  • -links<连接数目>:查找符合指定的硬连接数目的文件或目录;

  • -lname<范本样式>:指定字符串作为寻找符号连接的范本样式;

  • -ls:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出;

  • -maxdepth<目录层级>:设置最大目录层级;

  • -mindepth<目录层级>:设置最小目录层级;

  • -mmin<分钟>:查找在指定时间曾被更改过的文件或目录,单位以分钟计算;

  • -mount:此参数的效果和指定“-xdev”相同;

  • -mtime<24小时数>:查找在指定时间曾被更改过的文件或目录,单位以24小时计算;

  • -name<范本样式>:指定字符串作为寻找文件或目录的范本样式;

  • -newer<参考文件或目录>:查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录;

  • -nogroup:找出不属于本地主机群组识别码的文件或目录;

  • -noleaf:不去考虑目录至少需拥有两个硬连接存在;

  • -nouser:找出不属于本地主机用户识别码的文件或目录;

  • -ok<执行指令>:此参数的效果和指定“-exec”类似,但在执行指令之前会先询问用户,若回答“y”或“Y”,则放弃执行命令;

  • -path<范本样式>:指定字符串作为寻找目录的范本样式;

  • -perm<权限数值>:查找符合指定的权限数值的文件或目录;

  • -print:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式为每列一个名称,每个名称前皆有“./”字符串;

  • -print0:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式为全部的名称皆在同一行;

  • -printf<输出格式>:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式可以自行指定;

  • -prune:不寻找字符串作为寻找文件或目录的范本样式;

  • -regex<范本样式>:指定字符串作为寻找文件或目录的范本样式;

  • -size<文件大小>:查找符合指定的文件大小的文件;

    • b —— 块(512字节)

    • c —— 字节

    • w —— 字(2字节)

    • k —— 千字节(1024字节)

    • M —— 兆字节(1048576字节)

    • G —— 吉字节 (1073741824字节)

  • -true:将find指令的回传值皆设为True;

  • -typ<文件类型>:只寻找符合指定的文件类型的文件;

    • b - 块设备文件。

    • d - 目录。

    • c - 字符设备文件。

    • p - 管道文件。

    • l - 符号链接文件。

    • f - 普通文件。

  • -uid<用户识别码>:查找符合指定的用户识别码的文件或目录;

  • -used<日数>:查找文件或目录被更改之后在指定时间曾被存取过的文件或目录,单位以日计算;

  • -user<拥有者名称>:查找符和指定的拥有者名称的文件或目录; -version或——version:显示版本信息;

  • -xdev:将范围局限在先行的文件系统中;

  • -xtype<文件类型>:此参数的效果和指定“-type”参数类似,差别在于它针对符号连接检查。

组合条件:在要要查找的选项前面加

  • -a:与,同时满足,可省略

  • -o:或,一个满足

  • -not,!非。取反

提示:根据权限查找: -perm [+|-]MODE 精确匹配 +MODE:任何一类用户的任何一位权限匹配即可,常用于查找某类用用户的某特定权限是否存在 ,-MODE: 每类用户的指定要检查的权限位都匹配 ,例如:
文件权限:644
-perm 600:不匹配
-perm +222:匹配,查找用户有写权限
-perm +002:不匹配,0表示不查看
-perm -444:匹配

查找条件

根据文件名查找

  • -name "pattern"

  • -iname "pattern" :支持glob风格的通配符;

  • -regex pattern:基于正则表达式模式查找文件,匹配是整个路径,而非其名;

根据文件从属关系查找

  • -user USERNAME:查找属主指定用户的所有文件;

  • -group GRPNAME:查找属组指定组的所有文件;

  • -uid UID:查找属主指定的UID的所有文件;

  • -gid GID:查找属组指定的GID的所有文件;

  • -nouser:查找没有属主的文件;

  • -nogroup:查找没有属组的文件;

根据文件的类型查找

  • -type TYPE:
    f: 普通文件
    d: 目录文件
    l:符号链接文件
    b:块设备 文件
    c:字符设备文件
    p:管道文件
    s:套接字文件

组合测试

与:-a, 默认组合逻辑;
或:-o
非:-not, !

根据文件的大小查找

  • -size [+|-]#UNIT:常用单位:k, M, G
    #UNIT:(#-1, #]
    -#UNIT:[0,#-1]
    +#UNIT:(#, oo)

根据时间戳查找

以“天”为单位

  • -atime [+|-]#
    #:[#, #-1)
    -#:(#, 0]
    +#:(oo, #-1]

  • -mtime

  • -ctime

以“分钟”为单位:

  • -amin

  • -mmin

  • -cmin

根据权限查找

  • -perm [/|-]mode
    mode:精确权限匹配;
    /mode:任何一类用户(u,g,o)的权限中的任何一位(r,w,x)符合条件即满足;9位权限之间存在“或”关系;
    -mode:每一类用户(u,g,o)的权限中的每一位(r,w,x)同时符合条件即满足;9位权限之间存在“与”关系;

处理动作

  • -print:输出至标准输出;默认的动作;

  • -ls:类似于对查找到的文件执行“ls -l”命令,输出文件的详细信息;

  • -delete:删除查找到的文件;

  • -fls /PATH/TO/SOMEFILE:把查找到的所有文件的长格式信息保存至指定文件中;

  • -ok COMMAND {} ; :对查找到的每个文件执行由COMMAND表示的命令;每次操作都由用户进行确认;

  • -exec COMMAND {} ; :对查找到的每个文件执行由COMMAND表示的命令;

注意:find传递查找到的文件路径至后面的命令时,是先查找出所有符合条件的文件路径,并一次性传递给后面的命令;但是有些命令不能接受过长的参数,此时命令执行会失败;另一种方式可规避此问题:

find | xargs COMMAND

举例

查找/var目录下属主为root,且属组为mail的所有文件或目录;

# find /var/ -user root -a -group mail  -ls

查找/usr目录下不属于root, bin或hadoop的所有文件或目录;用两种方法;

~]# find /usr -not -user root -a -not -user bin -a -not -user hadoop
~]# find /usr -not \( -user root -o -user bin -o -user hadoop \) -ls

查找/etc目录下最近一周内其内容修改过,且属主不是root用户也不是hadoop用户的文件或目录;

~]# find /etc -mtime -7 -a -not \( -user root -o -user hadoop \) -ls
~]# find /etc -mtime -7 -a -not -user root -a -not -user hadoop -ls

查找当前系统上没有属或属组,且最近一周内曾被访问过的文件或目录;

~]# find  /  \( -nouser -o -nogroup \)  -atime  -7  -ls

查找/etc目录下大于1M且类型为普通文件的所有文件;

~]# find /etc -size +1M -type f -exec ls -lh {} \;

查找/etc目录下所有用户都没有写权限的文件;

~]# find /etc -not -perm /222 -type f -ls                   

查找/etc目录至少有一类用户没有执行权限的文件;

~]# find /etc -not -perm -111 -type f -ls

查找/etc/init.d/目录下,所有用户都有执行权限,且其它用户有写权限的所有文件;

~]# find /etc -perm -113 -type f -ls

xargs

xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理。通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从文件的输出中读取数据。xargs的默认命令是echo,这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。

参数

  • -0 :当sdtin含有特殊字元时候,将其当成一般字符,像空白或引号等。

  • -a file:从文件中读入作为sdtin

  • -e flag :注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止。

  • -n num:后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。

  • -p:操作具有可交互性,每次执行comand都交互式提示用户选择,当每次执行一个argument的时候询问一次用户

  • -t:表示先打印命令,然后再执行。

  • -i 或者是-I:这得看linux支持了,将xargs的每项名称,一般是一行一行赋值给{},可以用{}代替。

  • -r :如果没有要处理的参数传递给xargs,xargs 默认是带空参数运行一次,如果你希望无参数时,停止 xargs,直接退出,使用 -r 选项即可,其可以防止xargs 后面命令带空参数运行报错。

  • -s num xargs后面那个命令的最大命令行字符数(含空格)

  • -L 从标准输入一次读取num行送给Command命令 ,-l和-L功能一样。

  • -d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符。

  • -x exit的意思,如果有任何 Command 行大于 -s Size 标志指定的字节数,停止运行 xargs 命令,-L -I -n 默认打开-x参数,主要是配合-s使用。

  • -P 修改最大的进程数,默认是1,为0时候为as many as it can 。

举例

-0选项:

[root@hpf-linux test]# find /root/test -type f -print0
/root/test/text1/root/test/text4/root/test/text2/root/test/text3
[root@hpf-linux test]# find /root/test -type f -print0 |xargs 
xargs: 警告: 输入中有个 NUL 字符。它不能在参数列表中传送。您是想用 --null 选项吗?
/root/test/text1
[root@hpf-linux test]# find /root/test -type f -print0 |xargs -0
/root/test/text1 /root/test/text4 /root/test/text2 /root/test/text3

-a选项:
···
[root@hpf-linux test]# cat text1
1 apple
2 pear
3 banana
[root@hpf-linux test]# xargs -a text1 echo
1 apple 2 pear 3 banana
···
-e选项:

[root@hpf-linux test]# xargs -a text1 -E "pear" echo
1 apple 2
[root@hpf-linux test]# cat text1 |xargs -E "pear"
1 apple 2

-n 选项:

[root@hpf-linux test]# cat text1 |xargs -n 4 
1 apple 2 pear
3 banana
[root@hpf-linux test]# cat text1 |xargs -n 3
1 apple 2
pear 3 banana

-p 选项:

[root@hpf-linux test]# cat text1 |xargs -p
/bin/echo 1 apple 2 pear 3 banana ?...y
1 apple 2 pear 3 banana

-t 选项:

[root@hpf-linux test]# cat text1 |xargs -t -p
/bin/echo 1 apple 2 pear 3 banana ?...y
1 apple 2 pear 3 banana
[root@hpf-linux test]# cat text1 |xargs -t 
/bin/echo 1 apple 2 pear 3 banana 
1 apple 2 pear 3 banana

-i 选项:

[root@hpf-linux test]# ls |xargs -t -i mv {} {}.bak
mv text1 text1.bak 
mv text2 text2.bak 
mv text3 text3.bak 
mv text4 text4.bak 
[root@hpf-linux test]# ls
text1.bak  text2.bak  text3.bak  text4.bak

-r 选项:

[root@hpf-linux test]# echo ""|xargs -t mv
mv 
mv: 缺少了文件操作数
请尝试执行"mv --help"来获取更多信息。
[root@hpf-linux test]# echo ""|xargs -t -r mv

-s 选项:

[root@hpf-linux test]# cat text1.bak |xargs  -s 9 echo
aaa
bbb
ccc
ddd
a b
[root@hpf-linux test]# cat text1.bak |xargs  -s 4 echo
xargs: can not fit single argument within argument list size limit      #length(echo)=4
[root@hpf-linux test]# cat text1.bak |xargs  -s 8 echo
xargs: argument line too long      #length(echo)=4,length(aaa)=3,length(null)=1,total_length=8

-L 选项:

[root@hpf-linux test]# cat text1.bak |xargs -L 1 echo
1 apple
2 pear
3 banana
[root@hpf-linux test]# cat text1.bak |xargs -L 2 echo
1 apple 2 pear
3 banana
[root@hpf-linux test]# cat text1.bak |xargs -L 3 echo
1 apple 2 pear 3 banana

xargs和find

在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现 溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。find命令把匹配到的文件 传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一 批,并如此继续下去。
在有些系统中,使用-exec选项会 为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而 效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目 都会根据该命令的选项及系统内核中相应的可调参数来确定。
管道是把一个命令的输出传递给另一个命令作为输入,比如:command1 | command2但是command2仅仅把输出的内容作为输入参数。find . -name "install.log" -print打印出的是install.log这个字符串,如果仅仅使用管道,那么command2能够使用的仅仅是install.log这个字符串, 不能把它当作文件来进行处理。
当然这个command2除了xargs。xargs就是为了能够对find搜索到的文件进行操作而编写的。它能把管道传来的字符串当作文件交给其后的命令执行。

举例

显示从管道传来的内容,仅仅作为字符串来处理:

# find . -name "install.log" -print | cat
./install.log     

将管道传来的内容作为文件,交给cat执行。也就是说,该命令执行的是如果存在install.log,那么就打印出这个文件的内容。

# find . -name "install.log" -print | xargs cat
aaaaaa                                                     

在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:

# find . -perm -7 -print | xargs chmod o-w

查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件

# find . -type f -print | xargs file
./liyao: empty

尝试用rm 删除太多的文件,你可能得到一个错误信息:/bin/rm Argument list too long. 用xargs 去避免这个问题

$find ~ -name ‘*.log’ -print0 | xargs -i -0 rm -f {}

查找所有的jpg 文件,并且压缩它

# find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz

拷贝所有的图片文件到一个外部的硬盘驱动

# ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory

当你尝试用rm 删除太多的文件,你可能得到一个错误信息:/bin/rm Argument list too long. 用xargs 去避免这个问题

# find ~ -name ‘*.log’ -print0 | xargs -0 rm -f

获得/etc/ 下所有*.conf 结尾的文件列表,有几种不同的方法能得到相同的结果,下面的例子仅仅是示范怎么实用xargs ,在这个例子中实用 xargs将find 命令的输出传递给ls -l

# find /etc -name "*.conf" | xargs ls –l

假如你有一个文件包含了很多你希望下载的URL, 你能够使用xargs 下载所有链接

# cat url-list.txt | xargs wget –c

查找所有的jpg 文件,并且压缩它

# find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz

使用 vi 逐个打开此目录的文件:

#  file * | grep ASCII | cut -d":" -f1 | xargs vi 

限制每个命令行仅使用两个参数:

# file * | grep ASCII | cut -d":" -f1 | xargs -t -n2 ls -ltr 

Linux 文件查找