5.2.1: 基础命令 - 文件定位(find)



1. 文件定位命令

命令:which

作用:搜索命令用
语法:which 命令名称
参数:-a 不仅仅是第一个被找到的命令,所有被搜索到的命令都会列出。

# cd是一个内置命令,不在PATH内,所以下面的which搜索不到cd
type cd
cd is a shell builtin

which cd
/usr/bin/which: no cd in (/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)

只是在系统定义的PATH路径下搜索。


命令:whereis

作用:在特定的多个文件夹里搜索文件(/bin:/sbin:/usr/bin:/usr/sbin:man文档的相关文件夹等)
语法:whereis 参数 关键字
参数:


命令:locate

作用:从特定资料库里查询文件

语法:locate keywords

# 安装方法
yum install -y mlocate

# 更新一下数据库
updatedb

系统每天凌晨4点自动updated
资料库文件路径/var/lib/mlocate/mlocat.db


命令:find

说明:最强大的文件定位工具。

语法:find [PATH] [option] [action]

参数:-mtime

含义:以改变文件内容时间为搜索条件查询文件

事先约定,从现在开始往前24小时为第1天,n=1。以此类推再往前推24小时是第2天,n=2

"-mtime  n", n为数字,意为查询第n+1天当天24小时内改动过内容的文件;  
"-mtime +n", 意为查询 n+1天之前(不含n+1天本身)被改动过內容的文件;  
"-mtime -n", 列出在 n 天之內(含 n 天本身)被改动过内容的文件;  
"-newer file", file 为一个已存文件,列出比 file被改动内容更早之前的文件。


                                      4
                                   <----->
                                       -4<----------------------->
<----------------------------------|+4
<----------------------|-----|-----|-----|-----|-----|-----|-----|
                       7     6     5     4     3     2     1    现在

从上图可以看出,当n=4的时候

-mtime 4 是查询第5天改动过内容的文件;

-mtime +4 是查询5天前改动过内容的文件;

-mtime -4 是查询4天内改动过内容的文件。

参数:-mmin

含义:同-mtime,只是n不代表天数,代表分钟。

参数:-type

含义:以文件类型为搜索条件查询文件

类型可以是:

参数:-i

含义:忽略查询条件的大小写

参数:-inum

含义:以文件的inode号为查询条件查询文件。

可用于删除文件名乱码的文件

# 语法:find 路径 -inum inode号 | xargs rm
ll -i fdsfdsafdsafdew
415032 -rw-r--r--. 1 root root 0 Apr 26 18:31 fdsfdsafdsafdew

# 使用下面语句即可删除
find . -inum 415032 | xargs rm

参数:-exec

作用:find的选项,用来将find查询的结果执行额外的命令

语法: find 路径 -exec command \;

find . -maxdepth 1 -perm /400 -type f -exec ls {} \;  

# 原理图:
# +================+ -------------> ++
# |                |                ||
# find / -perm +7000  -exec  ls -l  {}  \;
#                     |   |             ||
#                     +===+ ----------> ++

# {} 代表的是『由 find 找到的內容』,如上所示,find 的结果会被放置到 {} 位置中;  
# -exec 一直到 (\;) 是关键字,代表 find 额外动作的开始 (-exec) 到結束 (\;) ,在这中间的就是 find 指令內的额外动作。 在本例中就是『 ls -l {} 』!  

因为;在 bash 环境下是有特殊意义的,因此利用反斜线来转义。

上图及解释引自鸟哥的私房菜

# "{}"有无的区别
# 有{}时,符合条件的全部被ls出来
find . -maxdepth 1 -perm /400 -type f -exec ls -l {} \;
-r-------- 1 root root 0 Dec 12 13:42 ./004
-r-s------ 1 root root 0 Dec 12 13:46 ./006
-rw-rw-rw- 1 root root 0 Dec 12 11:51 ./777

# 无{}时,所有文件都被ls出来,执行三次是因为有三个匹配项
find . -maxdepth 1 -perm /400 -type f -exec ls \;
001  002  003  004  005  006  007  017  037  077  177  377  777
001  002  003  004  005  006  007  017  037  077  177  377  777      
001  002  003  004  005  006  007  017  037  077  177  377  777

#========================

# -exec不支持命令别名
find . -maxdepth 1 -perm /400 -type f -exec ll {} \;
find: 'll': No such file or directory
find: 'll': No such file or directory
find: 'll': No such file or directory
# 为什么会显示这样的结果呢?
# 因为-exec是不支持alias过的命令的,而ll就是ls -l的alias

#========================

# 批量修改名称命令
find ./* -exec mv {} {}_bak \;

参数:-ok

作用: 和-exec类似,但会询问用户,若用户同意则执行,若拒绝,则返回错误

语法: find 路径 [匹配条件 <匹配内容>] -ok <command> {} \;

#"-ok"和";"成对,但";"有特殊意义,所以需要加上转义符号"\"
#当find匹配到了一个文件"sort.txt"会首先询问你是否执行该命令
find . -maxdepth 1 -name '*.txt' -ok ls {} \;
< ls ... ./md.txt > ? y
./md.txt
< ls ... ./sort.txt > ? y
./sort.txt
< ls ... ./1.txt > ? y
./1.txt
< ls ... ./regep.txt > ? y
./regep.txt
#
# 而-exec直接就会执行后面的命令
find . -maxdepth 1 -name '*.txt' -exec ls {} \;
./md.txt
./sort.txt
./1.txt
./regep.txt

参数:-perm

含义:使用权限来匹配

语法:

# 准备文件
# 分别创建不同权限的文件
ll perm | awk 'NR>1{printf("perm:%-11s name:%s\n",$1,$9)}'
perm:----------   name:001
perm:-----w----   name:002
perm:---------x   name:003
perm:-r--------   name:004
perm:---------T   name:005
perm:-r-s------   name:006
perm:-------rw-   name:007
perm:---x------   name:017
perm:-----w-rw-   name:037
perm:----rw-rw-   name:077
perm:---x-w-r--   name:177
perm:--w-rw-rw-   name:377
perm:-rw-rw-rw-   name:777

# 三种方式查找权限066 即为---rw-rw-

# 绝对查找066
find . -perm 066 -ls |sed 's/[[:space:]]\+/ /g'|cut -d ' ' -f 3,11
----rw-rw- ./077
# 只有数字"066"严格匹配

# 模糊匹配/066,只要9位权限中有r或者w的全部匹配
find . -perm /066 -ls |sed 's/[[:space:]]\+/ /g'|cut -d ' ' -f 3,11
-----w---- ./002
---x-w-r-- ./177
-------rw- ./007
--w-rw-rw- ./377
----rw-rw- ./077
-rw-rw-rw- ./777
-----w-rw- ./037

# 最小化匹配-066,只要不小于066权限的都匹配
find . -perm -066 -ls |sed 's/[[:space:]]\+/ /g'|cut -d ' ' -f 3,11
--w-rw-rw- ./377
----rw-rw- ./077
-rw-rw-rw- ./777

管道符特殊用法:xargs [参数] 命令

find ***|xargs -i mv {} {}.bak
# 参数-i 代表把前面的信息一条一条分批的处理

2. 执行find命令,遇到如下错误

2.1 错误信息

find . -name test*
find: paths must precede expression: test.log
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

ls test*
test2.sh  test.log  test.sh

2.2 解决办法

find . -name "test*"
./test.sh
./test2.sh
./test.log

扩展阅读:关于find -name报错“find: paths must precede expression:”