一个Linux系统包含非常多的文件,我们有时候如果忘记了路径,该如何去寻找?
这边分享两个通过locate
和find
命令查找文件的心得.
locate - 简单文件查找方式
查找/var/www
下所有php文件
locate /var/www/*.php
假如我们需要查找一个文件名为 bak.sh的文件
locate bak.sh
结果显示(显示完整的路径):
/home/bak/bak.sh
我忘记后缀了,只记得名字,没事locate也能帮你搞定
locate bak
结果显示:
/home/test/bak.sh
/home/test/bak/bak.sql
/home/bak/bak.sh
等等......
太多了,还是找不到,不过我想起来了,应该是在一个文件目录是以bak结尾的的文件夹下的bak开头的文件,即 xxxbak/bakxxxx
,那就继续使用locate试试吧
locate bak/bak
这下结果就少多了
/home/test/bak/bak.sql
/home/bak/bak.sh
如果搜索的是一个带路径的.locate 命令将会搜索它的路径名数据库,输出任一个包含字符串“bak/bak”的路径名
当然,也可以通过与其它命令结合使用,比如
locate bak | grep bin
结果显示:
/bin/bbak
/bin/bak2
/bin/bakkdfd
/usr/bin/dfdfdbak
/usr/bin/gdbak
除了locate
我们也可以使用find
命令来查找我们想要的文件
find - 复杂的文件查找方式
把家目录下所有的文件列出:
find ~
如果只是要看有多少个文件的话,就这样
find ~ | wc -l
find 命令的魅力所在就是它能够被用来识别符合特定标准的文件。例如,我只想看下有多少个目录:
find ~ -type d | wc -l
那么只想要普通文件呢:
find ~ -type f | wc -l
find 支持的条件类型:
* b 块设备文件
* c 字符设备文件
* d 目录
* f 普通文件
* l 符号链接
find 就这么简单吗?当然不是,我们还可以根据文件名称,文件大小,文件创建的时间来进行筛选,比如我要搜最后一次修改是在一天之前,超过1M,后缀是.txt的文件:
find ~ -name "*.txt" -ctime 1 -size +1M
这个例子中,我们加入了三个参数, -name,-ctime,-size搜索范围大大减小了,-name很容易理解,-ctime 1 表示最后修改时间在1*24 小时之前的,-size +1M表示文件大小超过1M的,如果是-1M 表示文件大小小于1M的,如果不指定则表示精确匹配。
我们先看下文件大小的单位:
* b 512 个字节块。如果没有指定单位,则这是默认值。
* c 字节
* w 两个字节的字
* k 千字节(1024个字节单位)
* M 兆字节(1048576个字节单位)
* G 千兆字节(1073741824个字节单位)
下面列一些,比较常用的筛选条件:
* -cmin n 匹配的文件和目录的内容或属性最后修改时间正好在 n 分钟之前。 指定少于 n 分钟之前,使用 -n,指定多于 n 分钟之前,使用 +n。
* -cnewer file 匹配的文件和目录的内容或属性最后修改时间早于那些文件。
* -ctime n 匹配的文件和目录的内容和属性最后修改时间在 n*24小时之前。
* -empty 匹配空文件和目录。
* -group name 匹配的文件和目录属于一个组。组可以用组名或组 ID 来表示。
* -iname pattern 就像-name 筛选条件,但是不区分大小写。
* -inum n 匹配的文件的 inode 号是 n。这对于找到某个特殊 inode 的所有硬链接很有帮助
* -mmin n 配的文件或目录的内容被修改于 n 分钟之前。
* -mtime n 匹配的文件或目录的内容被修改于 n*24小时之前。
* -name pattern 用指定的通配符模式匹配的文件和目录。
* -newer file 匹配的文件和目录的内容早于指定的文件。当编写 shell 脚本,做文件备份时,非常有帮助。 每次你制作一个备份,更新文件(比如说日志),然后使用 find 命令来决定自从上次更新,哪一个文件已经更改了。
* -nouser 匹配的文件和目录不属于一个有效用户。这可以用来查找 属于删除帐户的文件或监测攻击行为。
* -nogroup 匹配的文件和目录不属于一个有效的组。
* -perm mode 匹配的文件和目录的权限已经设置为指定的 mode。mode 可以用 八进制或符号表示法。
* -samefile name 相似于-inum 测试条件。匹配和文件 name 享有同样 inode 号的文件。
* -size n 匹配的文件大小为 n。
* -type c 匹配的文件类型是 c。
* -user name 匹配的文件或目录属于某个用户。这个用户可以通过用户名或用户 ID 来表示。
这只是部分常用命令,更多命令参考手册
示例:
sudo find /usr/local/nginx -name nginx.conf #在 /usr/local/nginx 下查找 nginx.conf 文件
sudo find /usr/local/nginx -iname nginx.conf #在 /usr/local/nginx 下查找 nginx.conf 文件,忽略文件名称大小写
sudo find /home/ ! -name "*.gz" #查找不是 .gz 后缀的文件
sudo find /home/ -iname "demo.*" #查找名称为 demo 开头的文件,不区分文件名称大小写
sudo find . -type f #查找文件类型为文件
sudo find . -maxdepth 1 -type f #查找文件类型为文件,向下最大深度限制为1
sudo find . -type d #查找文件类型为目录
sudo find . -type f -atime -7 #查找7天之内访问过的文件
sudo find . -type f -atime +7 #查找超过7天的访问文件
sudo find . -type f -atime 7 #查找7天前的访问文件
sudo find . -type f -amin -10 #查找10分钟之内的访问文件
sudo find . -type f -amin 10 #查找超过10分钟的访问文件
sudo find . -type f -amin +10 #查找超过10分钟的访问文件
操作符
即使拥有了 find 命令提供的所有筛选条件,我们还需要一个更好的方式来描述筛选条件之间的逻辑关系。例如, 如果我们需要确定是否一个目录中的所有的文件和子目录拥有安全权限,怎么办呢? 我们可以查找权限不是0600的文件和权限不是0700的目录。幸运地是,find 命令提供了 一种方法来结合测试条件,通过使用逻辑操作符来创建更复杂的逻辑关系。 为了表达上述的测试条件,我们可以这样做:
find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
如果你有高级语言编程基础可能会比较容易理解,但是不理解也没关系,我们看下面的
find命令逻辑操作符列表:
* -and 如果操作符两边的测试条件都是真,则匹配。可以简写为 -a。 注意若没有使用操作符,则默认使用 -and。
* -or 若操作符两边的任一个测试条件为真,则匹配。可以简写为 -o。
* -not 若操作符后面的测试条件是真,则匹配。可以简写为一个感叹号(!)。
* () 把测试条件和操作符组合起来形成更大的表达式。这用来控制逻辑计算的优先级。 默认情况下,find 命令按照从左到右的顺序计算。经常有必要重写默认的求值顺序,以得到期望的结果。 即使没有必要,有时候包括组合起来的字符,对提高命令的可读性是很有帮助的。注意 因为圆括号字符对于 shell 来说有特殊含义,所以在命令行中使用它们的时候,它们必须 用引号引起来,才能作为实参传递给 find 命令。通常反斜杠字符被用来转义圆括号字符。
这样确实方便了不少,大部分情况都可以满足我查找文件了,就是如果我要操作文件还是要再写命令。No,强大的find怎么会没想到。下面我们看下find的预定义操作。
预定义操作
从 find 命令得到的结果列表很有用处,但是我们真正想要做的事情是操作列表 中的某些条目。幸运地是,find 命令允许基于搜索结果来执行操作。有许多预定义的操作和几种方式来 应用用户定义的操作。首先,让我们看一下几个预定义的操作:
find的预定义操作:
* -delete 删除当前匹配的文件。
* -ls 对匹配的文件执行等同的 ls -dils 命令。并将结果发送到标准输出。
* -print 把匹配文件的全路径名输送到标准输出。如果没有指定其它操作,这是 默认操作。
* -quit 一旦找到一个匹配,退出。
我们看下最后一个示例:
find ~ -type f -name '*.bak' -delete
删除家目录下后缀是.bak的普通文件
这边只是列了一些普通的用法,简单的操作,更多的细节以及强大的功能需要去看find的手册。
http://www.gnu.org/software/findutils/
)