Linux命令-Find

文章目录
  1. 基本使用
  2. 例子

在文本处理中,经常涉及到对文件或者目录的查找操作,find命令用的很多,每次用只会那些简单的用法,有时候还需要网上查,这次总结记录下吧。

基本使用

基本格式如下:

1
find [目录] [文件形式] [操作]

  • 目录的话,没什么好说的,默认当前目录.
  • 文件形式,或者说查找的特征,常用的有以下几个
    • -name: 最常用的,就是查找文件的名字, 可以用通配符符号,使用iname可以忽略大小写
    • -type: 指定要查找的类型,就跟Linux的文件形式一样,有s:socket文件,d:目录, f: 普通文件
    • -not: 否定选项,就是查找与后面选项相反的文件.
    • -mindepth, maxdepth: 就是限定搜索制定目录的深度。
    • -perm: 按照权限来查找, 支持八进制位以及符号的权限搜索.
    • -empty: 空文件,也就是0字节的文件
    • mtime系列。后续详细说明.
    • -size: 指定文件大小,+100M表示大于100M的,-100M表示小于100M的。
    • -exec: 就是后续的操作命令了,-exec ls {} \; 其中{}表示匹配的文件

例子

以下例子转载自: -Mommy, I found it! -Daddy, I found it!

首先创建如下的文件以及目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# vim create_sample_files.sh
touch MybashProgram.sh
touch mycprogram.c
touch MyCProgram.c
touch Program.c
mkdir backup
cd backup
touch MybashProgram.sh
touch mycprogram.c
touch MyCProgram.c
touch Program.c
# chmod +x create_sample_files.sh
# ./create_sample_files.sh
# ls -R
.:
backup MybashProgram.sh MyCProgram.c
create_sample_files.sh mycprogram.c Program.c
./backup:
MybashProgram.sh mycprogram.c MyCProgram.c Program.c

以下的例子均基于以上的文件。

1.按照名字查找: 这个基本就是最基本的用法了,会查找目录下的所有文件,包括子目录里面的.

1
2
3
4
$ find . -name "MyCProgram.c"
./backup/MyCProgram.c
./MyCProgram.c

或者使用-iname忽略大小写

1
2
3
4
5
6
$ find . -iname "MyCProgram.c"
./backup/mycprogram.c
./backup/MyCProgram.c
./mycprogram.c
./MyCProgram.c

2.使用maxdepth,以及mindepth限制搜索的层数

当前层为第1层,其子目录就为第二层了。

1
2
3
4
5
6
7
8
9
10
11
12
13
shomy@LiuPC:findtest$ find . -maxdepth 2 -iname "MyCProgram.c"
./backup/mycprogram.c
./backup/MyCProgram.c
./mycprogram.c
./MyCProgram.c
shomy@LiuPC:findtest$ find . -maxdepth 1 -iname "MyCProgram.c"
./mycprogram.c
./MyCProgram.c
shomy@LiuPC:findtest$ find . -mindepth 2 -iname "MyCProgram.c"
./backup/mycprogram.c
./backup/MyCProgram.c

3.使用-exec执行命令 在找到符合条件的文件时,可以接着执行一些命令,格式就是:

1
2
3
4
5
shomy@LiuPC:findtest$ find -iname "MyCProgram.c" -exec md5sum {} \;
d41d8cd98f00b204e9800998ecf8427e ./backup/mycprogram.c
d41d8cd98f00b204e9800998ecf8427e ./backup/MyCProgram.c
d41d8cd98f00b204e9800998ecf8427e ./mycprogram.c
d41d8cd98f00b204e9800998ecf8427e ./MyCProgram.c

选项就是-exec, 后面紧跟命令,{}代表的是执行命令的当前文件,\;这个需要有。 比如查看详细信息:

1
2
3
4
5
shomy@LiuPC:findtest$ find -iname "MyCProgram.c" -exec ls -l {} \;
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 ./backup/mycprogram.c
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 ./backup/MyCProgram.c
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 ./mycprogram.c
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 ./MyCProgram.c

4.相反的匹配 就是使用-not命令来查找

1
2
3
4
5
6
shomy@LiuPC:findtest$ find -maxdepth 1 -not -iname "MyCProgram.c"
.
./backup
./Program.c
./create_sample_files.sh
./MybashProgram.sh

就是找名字不是MyCProgram的文件或者目录。

5.根据inode查找文件 每个文件都有独一无二的一个节点id, find同样支持根据inode查找文件。

1
find -inum id

这种查找应用场景,比如有俩文件名字很像,仅仅差一个空格如下:

1
2
3
4
5
$ touch "test_new"
$ touch "test_new "
$ ll -i
1725411 -rw-rw-r-- 1 shomy shomy 0 330 12:18 test_new
1725412 -rw-rw-r-- 1 shomy shomy 0 330 12:19 test_new

这样直接看的话,是看不出差别的,这时候想删除某一个的时候,就可以用inum

1
find -inum 1725412 -exec rm {} \;

还有一种情况就是比如说有如下俩文件:

1
2
-rw-rw-r-- 1 shomy shomy 0 3月 30 13:01 test_new?.txt
-rw-rw-r-- 1 shomy shomy 0 3月 30 13:01 test_new1.txt

此时如果想删除test_new?.txt的话,如果使用rm test_new?.txt的话,俩文件都会被删除, 这个时候,可以先找到test_new?.txt的inode, 然后再用上述过程删除

6.根据权限查找文件 使用-perm选项, 假设如下的文件:

1
2
3
4
5
6
7
8
# ls -l
total 0
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 all_for_all
-rw-r--r-- 1 root root 0 2009-02-19 20:30 everybody_read
---------- 1 root root 0 2009-02-19 20:31 no_for_all
-rw------- 1 root root 0 2009-02-19 20:29 ordinary_file
-rw-r----- 1 root root 0 2009-02-19 20:27 others_can_also_read
----r----- 1 root root 0 2009-02-19 20:27 others_can_only_read

例如要找到对group用户有读权限,并且忽略其他权限的文件,使用-g=r:

1
2
3
4
5
# find -pern -g=r -type f -exec ls -l {} \;
-rw-r--r-- 1 root root 0 2009-02-19 20:30 ./everybody_read
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 ./all_for_all
----r----- 1 root root 0 2009-02-19 20:27 ./others_can_only_read
-rw-r----- 1 root root 0 2009-02-19 20:27 ./others_can_also_read

然后如果想要找到只有读权限的文件,使用g=r 就可以:

1
2
# find -pern g=r -type f -exec ls -l {} \;
----r----- 1 root root 0 2009-02-19 20:27 ./others_can_only_read

-perm还支持八进制权限查询:

1
2
# find . -perm 040 -type f -exec ls -l {} \;
----r----- 1 root root 0 2009-02-19 20:27 ./others_can_only_read

7.根据大小查找文件 使用-size : - + 代表比给定大小 大 - - 表示比给定大小 小 - 单位可以用K,M,G等, 没有单位默认字节

1
2
3
4
5
6
7
8
# 查找大于100M的文件
find -size +100M
# 查找小于100M的文件
find -size -100M
# 查找等于100M的文件
find -size 100M

8.根据时间来查找 首先文件的时间属性,一般分为三种:

  • Access time: 访问时间,也就是访问该文件时,Atime更新
  • Modified time: 文件的修改时间,文件被修改时,Mtime更新
  • Change time: 文件本身的属性被改变时,Ctime更新,与Mtime不一样,这个主要是指inode发生变化,比如文件权限,所有人等变化。

另外针对时间的有两种量法:

  • min: 表示时间单位是分钟
  • time: 表示时间单位是天

因此针对以上的情况,就可以这样组合搜索了

  • -mmin n: 表示最后一次修改是在n分钟内
  • -mtime n: 表示最后一次修改是在n天内
  • -atime n: 表示最后一次访问是在n天内
  • 其它同理
1
2
3
4
5
查找一个小时内修过过的文件:
$ find -mmin 60
查找一天内修过过的文件:
$ find -mtime 1

上述是查找某个文件的时间,除此之外,也可以比较查找, newer 如下的文件:

1
2
3
4
5
6
7
8
9
10
11
12
shomy@LiuPC:findtest$ ll
总用量 24
drwxrwxr-x 3 shomy shomy 4096 3月 30 13:03 ./
drwxrwxr-x 4 shomy shomy 4096 3月 29 16:10 ../
drwxrwxr-x 2 shomy shomy 4096 3月 29 16:11 backup/
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 MybashProgram.sh
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 mycprogram.c
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 MyCProgram.c
-rw-rw-r-- 1 shomy shomy 0 3月 29 16:11 Program.c
-rw-rw-r-- 1 shomy shomy 0 3月 30 13:01 test_new
-rw-rw-r-- 1 shomy shomy 5 3月 30 16:34 test_new?
-rw-rw-r-- 1 shomy shomy 5 3月 30 16:34 test_new.tx

如下,查找修改时间比test_new晚的文件:

1
2
3
4
shomy@LiuPC:findtest$ find -newer test_new
.
./test_new?
./test_new.txt

同理:还有-anewer 以及-cnewer.对应的是访问时间以及inode修改的时间.

9.查找完成后执行 比如要找最大的5个文件:

1
find -type f -exec ls -s {} \; | sort -rn | head -5

首先是查找普通文件,不包括目录,然后执行ls -s,列出大小信息,接着借用管道排序,最后输出前5项.空间

10.-regex-name的区别 这两个都是按照文件名字查找,但是不一样的地方是,-regex是绝对路径,-name只是文件的名字 另外-regex后面的规则是正规的正则表达式形式,而-name则是通配符, 例如在正则表达式中.*是匹配任意长度的字符,而在-name*是匹配任意长度字符。 假设当前文件如下

1
2
3
4
5
6
shomy@LiuPC:findtest$ ll
drwxrwxr-x 3 shomy shomy 4096 3月 30 13:03 ./
drwxrwxr-x 4 shomy shomy 4096 3月 29 16:10 ../
-rw-rw-r-- 1 shomy shomy 0 3月 30 13:01 test_new
-rw-rw-r-- 1 shomy shomy 5 3月 30 16:34 test_new?
-rw-rw-r-- 1 shomy shomy 5 3月 30 16:34 test_new.txt

查找test_new文件如下:

1
2
3
4
5
6
7
8
shomy@LiuPC:findtest$ find -name 'test_new'
./test_new
# 未查找到:
shomy@LiuPC:findtest$ find -regex 'test_new'
shomy@LiuPC:findtest$ find -regex '.*test_new'
./test_new


暂时先到这里吧,总结都是一些基本用法, 还有一些关于正则表达式的还没涉及,以后再补上吧。