Linux系统是一个小系统,也是一个大系统。
说Linux是一个小系统,是因为linux简单、明快、高效,没有复杂的注册表,没有底层混乱的东西;说是一个大系统,是因为linux中有许许多多的文件,配置文件、头文件、临时文件等等,有时候你想精确的找到自己想要的文件并不是一件容易的事情。还好我们有查找文件的好工具,find。
find是系统中给我们提供的命令,它用来根据特定的选项、查找路径、查找条件,查找文件,并可辅以处理动作指定对查找到的文件作出指定的操作。
这里我们有必要说明下find大致的工作机制。为了说明find的工作机理,我们以whatis命令做以对比。whatis命令是查找命令在哪些man手册中有对应片段的命令,它可以高速查找速度非常快,这是因为它在后台维护了一个数据库(简单可以这么理解,这也是为什么我们刚装完系统后whatis命令使用会报错的原因,那个时候数据库还没有生成呢,需要手动通过makewhatis来创建)。因为数据并不是时刻在更新,因此,whatis查找并不十分精确,但速度快;find则不然,它实时对系统进行搜索查询,精度高,但是速度相对较慢。所以,在使用find命令时,要尽量避免对根目录等文件较多的目录全盘查找,应缩小查找范围。
本文内容主要有:
命令格式及简单说明
选项及示例
组合条件搜索
动作及示例
其他话题
一、命令格式及简单说明
find [option][path][expression][action]
option主要是find命令使用到的选项,-name,-iname,-user等
path是需要查找文件所在路径,默认不写情况下为当前工作目录
expression查找条件,默认为全部文件
action对查找到的文件执行的动作,默认为打印出查找到的文件列表
二、选项及示例
为了演示示例,在/tmp目录下创建文件,列表如下。如无特别说明,路径使用默认当前目录,省略。[root@station75 tmp]# ll
total 72
-rwsr-xr-x 1 root root 48568 Feb 26 16:53 cat
-rw-rw-r-- 1 hadoop hadoop 21 Feb 26 17:02 find1.txt
-rw-rw-r-- 1 hadoop hadoop 0 Feb 26 11:39 Find1.txt
-rw-rw-r-- 1 test test 0 Feb 26 11:38 find.txt
-rw-rw-r-- 1 test test 0 Feb 26 11:38 Find.txt
-rw------- 1 root root 921 Feb 26 16:50 fstab
-rw-r--r-- 1 root root 1615 Feb 26 11:34 passwd
-rw-r--r-- 1 root root 0 Feb 26 11:34 Passwd
-rw-r--r-- 1 root root 86 Feb 26 22:00 sum.sh
drwxrwxr-x 2 test test 4096 Feb 26 17:16 test
-rw-r--r-- 1 root root 0 Feb 26 11:36 test.txt
-rw-r--r-- 1 root root 0 Feb 26 11:36 Text.txt
[root@station75 tmp]#
1,基本选项
-name-name "文件名称" 根据文件名称精确查找,区分大小写
-iname根据名称查找,不区分大小写
-user根据文件属主查找
-group根据文件属组查找
-uid根据文件属主id(uid)查找。在用户已删除不知道用户名,知道uid的情况下使用较常见。即用户不在/etc/passwd文件中
-gid根据文件属组id(gid)查找。用户组已删除的情况下使用,即组不在/etc/group文件中
-nouser没有有效属主的文件,即用户不在/etc/passwd文件中
-nogroup没有有效属组的文件,即组不在/etc/group文件中
1.1 -name 根据文件名查找。找到名称为test的文件
#精确匹配到了test,首字母大写的文件、有后缀的test.txt均没有显示
[root@station75 tmp]# find -name "test"
./test
[root@station75 tmp]#
1.2 -iname 根据文件名称查找,不区分大小写。查找名字为find。
[root@station75 tmp]# find -iname "find1.txt"
./Find1.txt
./find1.txt
[root@station75 tmp]#
1.3 -user 根据用户属主查找。找到属主是hadoop的文件
[root@station75 tmp]# find -user hadoop
./Find1.txt
./find1.txt
[root@station75 tmp]#
1.4 -group 根据用户属组查找。找到属组是test的文件
[root@station75 tmp]# find -group test
./find.txt
./Find.txt
./test
[root@station75 tmp]#
1.5 -uid 根据uid查找。为了演示效果,这里我删除用户test
#这里删除用户。可以看到/tmp下,原来属主和属组是test的文件的属主和属组
#都显示为id,而不是名称
[root@station75 tmp]# userdel test
[root@station75 tmp]# ll
total 72
-rwsr-xr-x 1 root root 48568 Feb 26 16:53 cat
-rw-rw-r-- 1 hadoop hadoop 21 Feb 26 17:02 find1.txt
-rw-rw-r-- 1 hadoop hadoop 0 Feb 26 11:39 Find1.txt
-rw-rw-r-- 1 500 500 0 Feb 26 11:38 find.txt
-rw-rw-r-- 1 500 500 0 Feb 26 11:38 Find.txt
-rw------- 1 root root 921 Feb 26 16:50 fstab
-rw-r--r-- 1 root root 1615 Feb 26 11:34 passwd
-rw-r--r-- 1 root root 0 Feb 26 11:34 Passwd
-rw-r--r-- 1 root root 86 Feb 26 22:00 sum.sh
drwxrwxr-x 2 500 500 4096 Feb 26 17:16 test
-rw-r--r-- 1 root root 0 Feb 26 11:36 test.txt
-rw-r--r-- 1 root root 0 Feb 26 11:36 Text.txt
-rw------- 1 root root 261 Feb 24 21:02 yum_save_tx-2014-02-24-21-02aXFt0p.yumtx
[root@station75 tmp]#
查找uid是500的文件
[root@station75 tmp]# find -uid 500
./find.txt
./Find.txt
./test
[root@station75 tmp]#
1.6 -gid 根据gid查找文件。查找gid是500的文件
[root@station75 tmp]# find -gid 500
./find.txt
./Find.txt
./test
[root@station75 tmp]#
1.7 -nouser 查找没有有效属主的文件
[root@station75 tmp]# find -nouser
./find.txt
./Find.txt
./test
[root@station75 tmp]#
1.8 -nogroup 查找没有有效属组的文件
[root@station75 tmp]# find -nogroup
./find.txt
./Find.txt
./test
[root@station75 tmp]#
2 ,type选项
-type f查找普通文件 file
d查找目录文件 directory
b查找块设备文件 block
c查找字符设备文件 char
l查找链接文件 link
p查找管道文件 pipe
s查找套接字文件 socket
示例,查找目录文件
#查找其他类型文件类似,此处不再重复演示
[root@station75 tmp]# find -type d
.
./.ICE-unix
./test
[root@station75 tmp]#
3,size选项
-size[+ | -]#uint 使用格式(#代表数字,unit代表单位,马帮写法)直接跟#unit查找指定大小的文件
uint可为k,M,G+#unit查找大于指定大小的文件,要注意的是大于指定大小1个单位内的,均视为是成功匹配
-#unit查找小于指定大小的文件,要注意的是小于指定大小1个单位内的,均视为是成功匹配
说明:这个是选项是比较繁杂的一个选项,特别要注意的是在匹配的时候,是要有一个单位的浮动的。下面简单以一个例子说明
#这里命令写的是-1M,实际中显示的是0小于0M的文件,即空文件
[root@station75 tmp]# find -size -1M -ls
917513 0 -rw-r--r-- 1 root root 0 Feb 26 11:36 ./Text.txt
917516 0 -rw-rw-r-- 1 hadoop hadoop 0 Feb 26 11:39 ./Find1.txt
917511 0 -rw-r--r-- 1 root root 0 Feb 26 11:36 ./test.txt
917514 0 -rw-rw-r-- 1 500 500 0 Feb 26 11:38 ./find.txt
917510 0 -rw-r--r-- 1 root root 0 Feb 26 11:34 ./Passwd
917515 0 -rw-rw-r-- 1 500 500 0 Feb 26 11:38 ./Find.txt
[root@station75 tmp]#
4,时间戳选项
以天为单位-atime访问时间
-mtime修改时间
-ctime改变时间
以分钟为单位-amin访问时间
-mmin修改时间
-cmin改变时间
格式:-atime[+ | -]#
这里,时间的概念与通常中我们认识也有所不同,需要调整。我们不可能查找未来的文件,因此一切依旧时间的查找都是对过去时间的文件查找。
以现在这一时间为基准,用图示来说明
-atime +2:表示从现在开始2天之前,就是B点之前的所有时间
-atime -2:指的是2天以内,就是现在至B点,这两天内
-atime 2:指的是两天前的情况,但是包含2天不到3天的时间,也就是途中包含B点到C点之间的时间
5,-perm选项
-perm (后跟mode,权限)后不跟任何符号,默认为精确匹配权限
-perm + mode任何一类用户的任一权限都满足,通常由于查找某类用户某特定权限是否满足
-perm - mode每类用户的指定要检查的权限位都匹配
查找权限为644的文件[root@station75 tmp]# find -perm 644
-rw-r--r-- 1 root root 1615 Feb 26 11:34 passwd
-rw-r--r-- 1 root root 0 Feb 26 11:34 Passwd
-rw-r--r-- 1 root root 86 Feb 26 22:00 sum.sh
-rw-r--r-- 1 root root 0 Feb 26 11:36 test.txt
-rw-r--r-- 1 root root 0 Feb 26 11:36 Text.txt
[root@station75 tmp]#
查找有可写权限的文件[root@station75 tmp]# find -perm +333
-rwsr-xr-x 1 root root 48568 Feb 26 16:53 cat
-rw-rw-r-- 1 hadoop hadoop 21 Feb 26 17:02 find1.txt
-rw-rw-r-- 1 hadoop hadoop 0 Feb 26 11:39 Find1.txt
-rw-rw-r-- 1 test test 0 Feb 26 11:38 find.txt
-rw-rw-r-- 1 test test 0 Feb 26 11:38 Find.txt
-rw------- 1 root root 921 Feb 26 16:50 fstab
-rw-r--r-- 1 root root 1615 Feb 26 11:34 passwd
-rw-r--r-- 1 root root 0 Feb 26 11:34 Passwd
-rw-r--r-- 1 root root 86 Feb 26 22:00 sum.sh
drwxrwxr-x 2 test test 4096 Feb 26 17:16 test
-rw-r--r-- 1 root root 0 Feb 26 11:36 test.txt
-rw-r--r-- 1 root root 0 Feb 26 11:36 Text.txt
[root@station75 tmp]#
三、动作及示例
动作默认为显示查找到的文件列表。常见的选项有
-ls以长格式输出各文件信息
-exec -command\对查找到的文件执行特定的命令
-ok -command\类似-exec 但是交互式的界面
这里有一个非常重要的技巧。使用{}占位符。
例如我们需要找到某个目录下以.xls结尾的文件,并将其重命名为.xlsx。那么我们就非常合适使用{}占位符来实现。find /tmp/ -iname "*xls" -exec move {} {}x \
这里要强调的是,占位符后一定要有空格。
四、组合搜索
组合搜索是将不不同的搜索条件用逻辑判断符号连接起来进行查询,以达到高效查询。-a相当于&&,同时满足前后两个条件
-o相当于|| ,满足前后一个条件即可
-not取反
示例:查找名称为name为test(不区分大小写),属主为test的文件find -iname test -a -user test
五、其他话题
在学习的过程中,使用find命令查找文件,然后试图用管道传递给下一个命令,然后出现错误。原来,find列出整个文件列表,而管道只能传输字符串。要实现使用管道接受find传送过来的数据,则需要使用xargs。格式:find |xargs command
六、结语
本文前半段是在完整的实验环境下写成的,由于实验环境遭到破坏,且无法还原,因此后面部分示例较少或者没有与上面的示例保持连贯性。在后续的版本更新中,会统一更新示例。