Linux中find命令用法全知道

find命令上篇----find初体验

1、find的出身和近况

由大名鼎鼎的findutils软件包来提供,这个软件包的最早历史可以追溯到1987年,而在1990年正式发布了1.0版本。findutils软件包发布了全新的4.6.0版本,这是时隔6年半之后。

这个软件包中包含了四大猛将:

find 命令(今天的主角)

xargs命令(find的好兄弟,常和find一起配合使用)

locate命令(用于快速定位文件名)

updatedb(用于更新文件名数据库的工具)

2、先教你一招

在实际工作中,一定会遇到要在某个目录下寻找某个具体文件的场景,这时,find命令就派上用场。

[linson@www ~]$ pwd

/home/linson

[linson@www ~]$ find . -name readfile13.sh

./readfile13.sh

点号(.):告诉find命令"我们要在哪一个文件夹里进行搜索"。点号(.)表示当前所在文件夹,也就是/home/linson文件夹。

-name readfile13.sh:表示我们要搜索/home/linson文件夹里有没有叫"readfile13.sh"的文件或文件夹。

find [path...] -name [pattern]

如果仔细观察,你会发现path后面跟着一个省略号(...),是的,这表示find命令允许我们同时指定多个要搜索的文件夹,我们来看一个例子。

#列出test文件夹里的内容,-1F表示每行展示一个,且标识出其类型

#注意这里的 -1 是数字 1,而不是字母 l 。

[linson@www ~]$ ls -1F

operation_tools/

the_vim_way/

[linson@www ~]$ find operation_tools the_vim_way -name roc

operation_tools/roc

the_vim_way/roc

如果指定了多个文件夹,但中间的某个文件夹不存在,那么find会怎么处理。

[linson@www ~]$ find 20170701 20170702 20170703 aaaa -name roc

20170701/roc

20170702/roc

20170703/roc

find: ‘aaaa’: 没有那个文件或目录

find会从左到右依次搜索每一个文件夹,如果存在,则搜索;如果不存在,则报错,并继续搜索下一个文件夹,直到所有文件夹都搜索完成为止。

2、find可以指定要搜索的对象类型

Linux的多种类型:

普通文件

目录(也叫文件夹)

符号链接文件

管道文件

设备文件

想搜索当前文件夹下的名字叫作roc的子文件夹,命令如下:

[linson@www ~]$ find . -type d -name rocc

./20170701/rocc

-type支持的类型很多:

d:文件夹

f:普通文件

l:符号链接文件

b:块设备

c:字符设备

p:管道文件

s:socket套接字

3、我要指定文件名后缀

指定文件名后缀,也是工作中很常见的一种搜索场景,比如要找到文件夹中所有的avi文件,就要用到这个功能。

假如想找出当前文件夹里所有普通文件(-type f)中名称后缀是".avi"的文件。

[linson@www ~]$ find . -type f -name "*.avi"

./20170701/lin.avi

4、我需要更精准地匹配

假如我们想搜索同时满足下面条件的普通文件:

名字以字母e开头

名字含有avi字串

名字以数字编号结尾

[linson@www ~]$ find . -type f -regex '.*/e.*avi.*[0-9]+$'

./20170702/edison.avi.12

5、按属主和属组来搜索

上面的内容,我们基本都是围绕文件名来进行搜索的,其实find还可以按照更丰富的信息来搜索,比如按照属主和属组来搜索。

想查找当前目录及其子文件夹中属主是"roc"、属组也是"roc"的普通文件有哪些:

[linson@www ~]$ find . -type f -user linson -group linson

./.bash_logout

./.bashrc

./.cache/imsettings/log

./.cache/tracker/db-versi

6、按照权限来搜索

想查找当前文件夹及子文件夹里权限设定为664(664对应的是rw-rw-r--)的所有普通文件:

[linson@www ~]$ find . -perm 664

./poetry_list.txt

-perm选项,用于设定权限,perm就是permission的简写,表示权限

[linson@www ~]$ find . -perm 664 -exec ls -lh {} \;

-rw-rw-r--. 1 linson linson 11 6月 18 17:33 ./.cache/tracker/miner-applications-locale.txt

-rw-rw-r--. 1 linson linson 10 6月 18 17:34 ./.cache/tracker/last-crawl.txt

-rw-rw-r--. 1 linson linson 5 6月 18 17:34 ./.cache/tracker/first-index.txt

-exec选项的作用就是允许我们将find出来的每一个对象指定为特定shell命令的参数来执行。

-exec:告诉find,我们要针对它搜索到的每一个对象执行特定的Shell命令。

ls -hl:便是我们指定的特定Shell命令

{}:在-exec用法中,{ }指代find搜索到的每一个对象。

\;:在-exec用法中,分号(;)表示特定Shell命令结束,为了防止转义,我们必须在分号前面加上反斜杠(\)。

步骤1:#先列出当前文件夹下的内容

[linson@www 20170701]$ ls

edison.avi edison.avi.12 lin.avi roc rocc topmem.c

步骤2:#我们看看权限为664的文件有哪些

[linson@www 20170701]$ find . -perm 664 -type f

./roc

./lin.avi

./topmem.c

./edison.avi

./edison.avi.12

步骤3:我们想把权限为664的文件都改个名,都加上后缀.new

[linson@www 20170701]$ find . -perm 664 -type f -exec mv {} {}.new \;

步骤4:查看是否生效

[linson@www 20170701]$ ls

edison.avi.12.new edison.avi.new lin.avi.new rocc roc.new topmem.c.new

7、按时间来搜索文件

-mmin +n\-n:

+n 表示在n分钟以前文件被修改过。

-n 表示在n分钟以内文件被修改过。

-cmin +n\-n:

+n 表示在n分钟以前文件状态有过改变

-n 表示在n分钟以内文件状态有过改变

-amin +n\-n:

-n 表示在n分钟以前文件被访问过

+n 表示在n分钟以内文件被访问过

看下5分钟以内有哪些文件被修改过

[linson@www 20170701]$ find . -type f -mmin -5

./edison.avi.new

再看一下5分钟以前有哪些文件被修改过

[linson@www 20170701]$ find . -type f -mmin +5

./roc.new

./lin.avi.new

./topmem.c.new

./edison.avi.12.new

-mtime +n\-n:用法和mmin类似,只是单位变成了"天"

-ctime +n\-n:用法和cmin类似,只是单位变成了"天"

-atime +n\-n:用法和amin类似,只是单位变成了"天"

搜索比某个特定文件新的文件

-newer file:搜索修改时间比file文件的修改时间近的

-anewer file:搜索访问时间比file文件的访问时间近的

-cnewer file:搜索状态变化时间比file文件的状态变化时间近的。

-newerXY:搜索X时间比file文件的Y时间近的。

8、newerXY选项

此选项是findutils软件包在4.3.3版本时加入的新特性,它实现了一个新的效果,那就是"针对两个对象的不同类型的时间进行比较",比如要搜索"访问时间"比指定文件的"修改时间"更近的文件。

一定要指定一个参数作为比较的对象,这个参数可以是一个具体的文件,也呆以是一个具体的时间值,比如 2016-02-12

X 和 Y,其实是两个占位符,用户可以根据自己的需求将它们替换成如下字母:

a:访问时间

B:诞生时间(birth time,往往只有BSD系统才有)

c:状态变化时间

m:修改时间

t:将所指定的参数理解为一个具体的时间值。

搜索当前文件夹下访问时间新于topmem.c.new文件的修改时间的普通文件

[linson@www ~]$ find . -type f -neweram readfile13.sh

搜索当前文件夹下修改时间新于readfile13.sh文件的访问时间的普通文件

[linson@www ~]$ find . -type f -newerma readfile13.sh

搜索当前文件夹下修改时间新于2017-07-05的普通文件

[linson@www ~]$ find . -type f -newermt 2017-07-04

搜索当前文件夹下修改时间新于2017-07-04 17:44:00的普通文件

[linson@www ~]$ find . -type f -newermt "2017-08-03 22:28:00"

./.cache/abrt/lastnotification

./.bash_history

./20170701/edison.avi.new

./.viminfo

9、找到那些大文件

查找当前目录及子目录下文件大小大于4k的所有文件

[linson@www ~]$ find . -type f -size +4k -exec ls -lh {} \;

-size n起到了关键作用,它是用来针对文件大小进行搜索的。n的具体用法有些复杂,

-size +4k : 表示搜索大于4k的文件

-size -4k : 表示搜索小于4k的文件

-size 4k : 表示搜索恰好等于4k的文件

-size 支持的单位包括:

b : 512 - byte 数据块

c :bytes

w : 两字节的字(words)

k :KB

M :MB

G :GB

10、我不想递归搜索

find命令默认情况下是会搜索指定文件夹里的子文件夹的,而且是递归向下搜索的。

find提供了-maxdepth选项来控制搜索的深度

[linson@www ~]$ find . -maxdepth 1 -size +4k -type f

./.bash_history

./set.txt

./declare.txt

./.vimrc

./.viminfo

./inputfile.tar

为了验证find有没有骗人,照例用-exec来确认一下:

[linson@www ~]$ find . -maxdepth 1 -size +4k -type f -exec ls -lh {} \;

-rw-------. 1 linson linson 13K 8月 3 22:51 ./.bash_history

-rw-rw-r--. 1 linson linson 140K 6月 26 22:19 ./set.txt

-rw-rw-r--. 1 linson linson 140K 6月 26 22:19 ./declare.txt

-rw-rw-r--. 1 linson linson 4.5K 7月 25 20:50 ./.vimrc

-rw-------. 1 linson linson 5.7K 8月 3 22:29 ./.viminfo

-rw-rw-r--. 1 linson linson 10K 7月 27 20:41 ./inputfile.tar

11、find可以设置多条件

find可以同时设置多个条件:

[linson@www ~]$ find . -type f -a -name "readfile*"

./readfile13.sh

./readfile14.sh

./readfile12.sh

./readfile11.sh

-a选项表示与( and )关系,这个命令的含义是搜索当前文件夹下即是"普通文件"并且"名字中含readfile字符串"的对象。

find [路径...] 表达式1 表达式2

等价于

find [路径...] 表达式1 -a 表达式2

12、再说说表达式

find表达式的一些重要的用法和规则

(expr):我们可以把一个表达式用小括号括起来,这样可以提升它的处理优先级,在一些有与或非组合的表达式里,会非常有用。

!expr:我们可以对一个表达式取反,取反之后仍然是一个表达式。

expr1 expr2:这个表达方法我们刚刚讲过,它表示两个表达式进行与(and)关系处理。

expr1 -a expr2:等价于expr1 expr2。如果expr1为假,就不会再评估expr2了。

expr1 -o expr2:表示对两个表达式求或(or)关系。如果expr1为真,则不会再评估expr2了。

expr1, expr2:这种属于列表表达式,两个表达式都会被评估,但其结果总是expr2的结果。

[linson@www ~]$ find . \( -type f -a -name "inputfile*" \) -o \( -type f -a -user lins \)

小括号前面都加了一个转义符(\),这是find使用小括号时的一个技巧。因为如果不使用转义符转义的话,那么小括号会被Shell所处理,而无法传递给find命令。

find命令下篇----find引出的正则知识

1、正则足足可以写一整本书

正则表达式,英文叫作Regular Expression,简写有很多种,比如regex、regexp或RE等,如果非要用一句话来定义正则表达式的话,那么引用百度百科的原话:

正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。

2、回忆find中如何使用正则

同时搜索满足下面条件的普通文件:

名字以字母e开头

名字含有avi字串

名字以数字编号结尾

[linson@www ~]$ find . -type f -regex '.*/e.*avi.*[0-9]+$'

./edison.avi.12

./20170702/edison.avi.12

[linson@www ~]$ find . -type f -regex '.*/e.*avi.*\[\[:digit:\]\]+$'

[linson@www ~]$ find . -type f -regex '.*/e.*avi.*[\d]+$'

[linson@www ~]$ find . -type f -regex '.*/e.*avi.*[0-9]+$'

./edison.avi.12

./20170702/edison.avi.12

3、Regextype在幕后指使

find命令是支持我们指定正则表达式的类型的。之所以有必要指定正则表达式类型,是因为正则表达式的语法不够统一,各类语法百花齐放,即使是针对同一种需求,也会有不同的解决方法。

find支持的正则表达式类型:

emacs:采用和GNU emacs编辑器兼容的正则表达式。这也是find默认的选项。

posix-awk:采用和POSIX awk命令兼容的正则表达式。

posix-basic:POSIX的基础正则表达式。

posix-egrep:和POSIX的egrep命令兼容的正则表达式。

posix-extended:POSIX的扩展正则表达式。

emacs类型

点号( . ):匹配除换行之外的任何单个字符。

加号( + ):代表其前面元素出现一次或多次。

问号( ? ):代表其前面元素出现零次或一次。

\+:匹配加号 ( + )。

\?:匹配问号 ( ? )。

中括号( [ ] ):用来表示一组字符集,如[0 -9]、[a -z],但只能正序不能倒序,比如[z-a]、[9-0]是错误的表达方式。另外,在中括号中,反斜线( \ )表示它字面的含义,没有其他特殊含义。

emacs类型不支持字符形式的类型,比如[ [ :digit: ] ]是不被支持的。

分组的话,请用"\("和"\)"括起来。而后用"\数字"的形式来指代某个分组,如"\2"就表示第二个括号分组。分组的次序主要取决于左小括号出现的顺序。

"或符号",请用"\|"表示

^表示匹配某一字符串的开端。

$表示匹配某一字符串的结尾。

emacs采用的是贪婪匹配,也就是总会匹配符合条件的最长串。

emacs类型支持一些常见的匹配类型:

\w:匹配一个word(即单词,由字母、数字、下划线组成)。

\W:和\w相反,用来匹配一个非单词(word)。

\

\>:匹配一个word的结尾。

\b:匹配一个word的两端。

\B:和\b相反,用来匹配一个非单词(word)的两端。

\`:匹配整个输入的开头。

\':匹配整个输入的结尾。

posix-awk类型

点号 ( . ):匹配除null之外的任何单个字符。

加号 ( + ):代表其前面元素出现一次或多次。

问号 ( ? ):代表其前面元素出现零次或一次。

\+:匹配加号( + )。

\?:匹配问号( ? )。

中括号([ ]):用来表示一组字符集,如[0-9]、[a-z],但只能正序不能倒序,比如[z-a]、[9-0]是错误的表达方式。另外,在中括号中,反斜线(\)用于转义它后面的字符。

posix-awk类型支持字符形式的类型,比如[[:digit:]]就表示单个十进制的数字。

posix-awk类型中,'\w'、'\W'、''、'\b'、'\B'、'`'和'\''都没有特殊含义,而只是简单的分别指代'w'、'W'、''、 'b'、 'B'、 '`'、 '''。

分组的话,直接使用()即可。而后用"\数字"的形式来指代某个分组,如"\2"就表示第二个括号分组。分组的次序主要取决于左小括号出现的顺序。

"或符号",请直接用"|"表示。

^代表一个字符串的开头,但如果^出现在中括号中,则表示中括号中原本指代的字符成员的相反内容,如[^0-9]则表示非数字。

$代表一个字符串的结尾。

支持区间匹配,用{ }表示前一字符出现的次数范围,如a表示匹配a出现的次数范围为m到n次。

posix-awk类型采用的是贪婪匹配,也就是说,总会匹配符合条件的最长串。

posix-basic类型

posix-basic正则表达式,简称BRE,即Basic Regular Expression。

点号(.):匹配除换行之外的任何单个字符。

星号(*):代表其前面元素出现零次或多次。

posix-basic中"+"符号和"?"符号都只其字面含义,而特殊含义要用\和\来代替。

^表示匹配某一字符串的开端。

$表示匹配某一字符串的结尾。

\{\}表示前一字符出现的次数范围,如a\表示匹配a出现的次数范围为m到n次。

分组的话,请用"\("和"\)"括起来。而后用"\数字"的形式来指代某个分组,如"\2"就表示第二个括号分组。分组的次序主要取决于左小括号出现的顺序。

posix-basic基本只支持这几种特性,甚至连或关系都不支持,看来真的是很基础,很简陋。

posix-egrep类型

egrep是很强大的命令,所以,posix-egrep当然也支持更灵活一些的匹配。

点号(.):匹配除换行之外的任何单个字符。

加号(+):代表其前面元素出现一次或多次。

问号(?):代表其前面元素出现零次或一次。

\+:匹配加号(+)

\?:匹配问号(?)。

中括号([ ]):用来表示一组字符集,如[0-9]、[a-z],但只能正序不能倒序,比如[z-a]、[9-0]是错误的表达方式。另外,在中括号中,反斜线(\)表示它字面的含义,没有其他特殊含义。

posix-egrep类型支持字符形式的类型,比如[[:digit:]]就表示单个十进制的数字。

posix-egrep类型支持一些常见的匹配类型,列举如下:

\w:匹配一个word。

\W:和\w相反

\

\>:匹配一个word的结尾。

\b:匹配一个word的两端。

\B:和\b相反。

\`:匹配整个输入的开头。

\':匹配整个输入的结尾。

我们继续看其他特性:

分组的话,直接使用()即可。而后用"\数字"的形式来指代某个分组,如"\2"就表示第二个括号分组。分组的次序主要取决于左小括号出现的顺序。

"或符号",请直接用"|"表示。

^代表一个字符串的开头,但如果^出现在中括号中,则表示中括号中原本指代的字符成员的相反内容,如[^0-9]则表示非数字。

$代表一个字符串的结尾。

"*"、"+"和"?"在posix-egrep中都是特殊字符,具有特殊作用。即"*"代表零个或多个,"+"代表一个或多个,"?"代表零个或一个。

{ }表示前一字符出现的次数范围,如a表示匹配a出现的次数范围为m到n次。

posix-egrep类型采用的是贪婪匹配,即总会匹配符合条件的最长串。

posix-extended类型

点号(.):匹配除null之外的任何单个字符。

加号(+):代表其前面元素出现一次或多次。

问号(?):代表其前面元素出现零次或一次。

\+:匹配加号(+)

\?:匹配问号(?)

中括号([ ]):用来表示一组字符集,如[0-9]、[a-z],但只能正序不能倒序,比如[z-a]、[9-0]就是错误的表达方式。另外,在中括号中,反斜线(\)只表示它字面的含义,没有其他特殊含义。

posix-extended类型支持字符形式的类型,比如[[:digit:]]就表示单个十进制的数字。

posix-extended类型支持一些常见的匹配类型,列举如下:

\w:匹配一个word。

\W:和\w相反。

\

\>:匹配一个word的结尾。

\b:匹配一个word的两端。

\B:和\b相反。

\`:匹配整个输入的开头。

\':匹配整个输入的结尾。

我们继续看其他特性:

分组的话,直接使用( )即可。而后用"\数字"的形式来指代某个分组,如"\2"就表示第二个括号分组。分组的次序主要取决于左小括号出现的顺序。

"或符号",请直接用"|"表示。

^代表一个字符串的开头,但如果^出现在中括号中,则表示中括号中原本指代的字符成员的相反内容,如[^0-9]则表示非数字。

{ }表示前一字符出现的次数范围,如a表示匹配a出现的次数范围为m到n次。

posix-egrep类型采用的是贪婪匹配,即总会匹配符合条件的最长串。

一个全景对比表格

注:八大匹配是指\w、\W、\、\b、\B、\`和\'这八个匹配字符

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180420A16Y7E00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券