16. Linux 查找文件

[TOC]

whereis 文件查找和比较

  • whereis 命令用来定位指令的二进制程序、源代码文件和 man 手册页等相关文件的路径。
  • whereis 命令只能用于程序名的搜索,而且只搜索二进制文件(参数 - b)、man 说明文件(参数 - m)和源代码文件(参数 - s)。如果省略参数,则返回所有信息。

find 相比,whereis 查找的速度非常快,这是因为 linux 系统会将系统内的所有文件都记录在一个数据库文件中,当使用 whereislocate 时,会从数据库中查找数据,而不是像 find 命令那样,通过遍历硬盘来查找,效率自然会很高。但是该数据库文件并不是实时更新,默认情况下时一星期更新一次,因此,我们在用 whereislocate 查找文件时,有时会找到已经被删除的数据,或者刚刚建立文件,却无法查找到,原因就是因为数据库文件没有被更新。

语法:whereis [-bmsu] [文件名称]

参数 含义
-b 只找 binary 文件
-m 只找在说明文件 manual 路径下的文件
-s 只找 source 来源文件
-u 没有说明档的文件

locate 查找文件

locate 命令用于快速搜索路径名数据库,并且输出每个与给定字符串相匹配的文件名。

Linux 发行版中发现的两个最常见的变体是 slocatemlocate,但是通常它们被名为 locate 的符号链接访问。

# 查找匹配程序的目录以“bin/”结尾,以“zip”开头的程序
$ locate bin/zip
/usr/bin/zipdetails

# 查询文件名中包含“zip”的文件,同时路径名中匹配“bin”。
locate zip | grep bin
/bin/bunzip2
/bin/bzip2
/bin/bzip2recover
/bin/gunzip
/bin/gzip
/lib/firmware/qed/qed_init_values_zipped-8.10.10.0.bin
/lib/firmware/qed/qed_init_values_zipped-8.10.5.0.bin

find 在目录层次结构中搜索文件 ⭐️⭐️⭐️

locate 程序只能依据文件名来查找文件,而 find 程序能基于各种各样的属性,搜索一个给定目录(以及它的子目录),来查找文件。

语法:find [OPTION] [path...] [expression]

find [path] -name fileName : 通过文件名查找
$ find /root -name test1
$ find /usr/bin -name zip -print    ##在 /usr/bin 目录中查找 zip 命令
$ find ~/ -name *.c -print          ##列出用户主目录下所有的 c 程序文件
find [path] -type fileType : 通过文件类型查找
find文件类型 描述
b 块设备文件
c 字符设备文件
d 目录
f 普通文件
| 符号链接
find /root -type d

# 输出主目录列表:
find ~

# 使用 wc 程序来计算文件的数量:
find ~ | wc -l
26129

# -type d 只搜索目录:
find ~ -type d | wc -l
3548

# -type f 只搜索文件:
find ~ -type f | wc -l
22463
通过指定时间查找
参数 含义
-atime +n Access time,访问或执行时间大于 n 天的文件
-ctime +n Create time,写入、更改 inode 属性(例如更改所有者、权限或者连接)时间大于 n 天的文件
-mtime +n Modified time,写入时间大于 n 天的文件

+n 表示大于n天,-n表示小于n天。

  • ls -| 命令可用来列出文件的 atime、ctime 和 mtime。
  • ls -|c filename : 列出文件的 ctime
  • ls -|u filename : 列出文件的 atime
  • ls -| filename : 列出文件的 mtime

根据文件大小和文件名来搜索:

# 查找所有文件名匹配 通配符模式 “*.JPG” 和文件大小大于 1M 的文件
find ~ -type f -name "\*.JPG" -size +1M | wc -l

find 大小单位:

字符 单位
b 512 个字节块。如果没有指定单位,则这是默认值。
c 字节
w 两个字节的字
k 千字节 (1024 个字节单位)
M 兆字节 (1048576 个字节单位)
G 千兆字节 (1073741824 个字节单位)

find 命令支持大量不同的测试条件。下表是列出了一些常见的测试条件:

测试条件 描述
-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 来表示。

操作符

描述测试条件之间的逻辑关系。

find 支持通过使用逻辑操作符来创建更复杂的逻辑关系。

# 查找权限不是 0600 的文件和权限不是 0700 的目录。
find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)

find 命令的逻辑操作符:

操作符 描述
-and 匹配如果操作符两边的测试条件都是真。可以简写为 -a。 注意若没有使用操作符,则默认使用 -and。
-or 匹配若操作符两边的任一个测试条件为真。可以简写为 -o。
-not 匹配若操作符后面的测试条件是真。可以简写为一个感叹号(!)。
() 把测试条件和操作符组合起来形成更大的表达式。这用来控制逻辑计算的优先级。 默认情况下,find 命令按照从左到右的顺序计算。经常有必要重写默认的求值顺序,以得到期望的结果。 即使没有必要,有时候包括组合起来的字符,对提高命令的可读性是很有帮助的。注意 因为圆括号字符对于 shell 来说有特殊含义,所以在命令行中使用它们的时候,它们必须用引号引起来,才能作为实参传递给 find 命令。通常反斜杠字符被用来转义圆括号字符。

有两个由逻辑操作符分开的表达式:

expr1 -operator expr2

# 对于文件,我们定义正确权限为 0600,目录则为 0711。
# 测试具有 “不正确” 权限的文件表达式为:
-type f -and -not -perms 0600
# 对于目录,表达式为(-and 可省):
-type d -and -not -perms 0700
# 组合以上,得到:
find ~ /( -type f -not -perms 0600 /) -or /( -type d -not -perms 0700 /)

表:find AND/OR 逻辑 :expr1 -operator expr2

expr1 的结果 操作符 expr2 is...
-and 总要执行
-and 从不执行
-or 从不执行
-or 总要执行

预定义的操作

find 命令允许基于搜索结果来执行操作。

几个预定义的 find 命令操作

操作 描述
-delete 删除当前匹配的文件。
-ls 对匹配的文件执行等同的 ls -dils 命令。并将结果发送到标准输出。
-print 把匹配文件的全路径名输送到标准输出。如果没有指定其它操作,这是 默认操作。
-quit 一旦找到一个匹配,退出。
find ~ # 默认使用 -print 操作
find ~ -print  # 同上

# 搜索用户主目录(和它的子目录)下搜索每个以. BAK 结尾的文件名,然后删除他们
find ~ -type f -name '*.BAK' -delete

# 每个测试和操作之间会默认应用 -and 逻辑运算符,即:
find ~ -type f -and -name '*.BAK' -and -print

当命令被充分表达之后,让我们看看逻辑运算符是如何影响其执行的:

测试/行为 只有... 的时候,才被执行
-print 只有 -type f and -name '.BAK'为真的时候
-name ‘.BAK’ 只有 -type f 为真的时候
-type f 总是被执行,因为它是与 - and 关系中的第一个测试/行为。

用户定义的行为

语法:-exec command {} ;

-exec rm '{}' ';'

# 通过使用 -ok 行为来代替 -exec,在执行每个指定的命令之前会提示用户
find ~ -type f -name 'foo*' -ok ls -l '{}' ';'

提高效率

# 命令会执行多次
find ~ -type f -name 'foo*' -exec ls -l '{}' ';'

# 命令只被执行一次而不是多次。
# 通过把末尾的分号改为加号,就激活了 find 命令的一个功能,把搜索结果结合为一个参数列表,然后执行一次所期望的命令。
find ~ -type f -name 'foo*' -exec ls -l '{}' +

限制范围的选项

这些选项被用来控制 find 命令的搜索范围。

选项 描述
-depth 指导 find 程序先处理目录中的文件,再处理目录自身。当指定 - delete 行为时,会自动 应用这个选项。
-maxdepth levels 当执行测试条件和行为的时候,设置 find 程序陷入目录树的最大级别数。
-mindepth levels 在应用测试条件和行为之前,设置 find 程序陷入目录数的最小级别数。
-mount 指导 find 程序不要搜索挂载到其它文件系统上的目录。
-noleaf 指导 find 程序不要基于搜索类似于 Unix 的文件系统做出的假设,来优化它的搜索。

xargs 从标准输入生成和执行命令行

xargs 命令会执行一个有趣的函数。它从标准输入接受输入,并把输入转换为一个特定命令的参数列表。

find ~ -type f -name 'foo\*' -print | xargs ls -l

# --null 选项,接受由 null 字符分离的输入。
find ~ -iname '*.jpg' -print0 | xargs --null ls -l

注意:当被放置到命令行中的参数个数相当大时,参数个数是有限制的。有可能创建的命令 太长以至于 shell 不能接受。当命令行超过系统支持的最大长度时,xargs 会执行带有最大 参数个数的指定命令,然后重复这个过程直到耗尽标准输入。执行带有 --show--limits 选项 的 xargs 命令,来查看命令行的最大值。

touch 更改文件时间

touch 命令通常被用来设置或更新文件的访问,更改,和修改时间。然而,如果一个文件名参数是一个不存在的文件,则会创建一个空文件。

stat 显示文件或文件系统状态

stat 命令会展示系统对 某个文件及其属性所知道的所有信息。

$ stat Agora_Recording_SDK_for_Linux_v2_2_2_FULL.tar.gz 
  File: 'Agora_Recording_SDK_for_Linux_v2_2_2_FULL.tar.gz'
  Size: 32172438        Blocks: 62840      IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 2230658     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-09-28 14:18:23.303057733 +0800
Modify: 2018-09-27 17:56:41.000000000 +0800
Change: 2018-09-28 11:15:15.673806664 +0800
 Birth: -

参考

程序 locateupdatedbfindxargs 都是 GNU 项目 findutils 软件包的一部分。
GNU Operating System - Findutils

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,719评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,337评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,887评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,488评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,313评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,284评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,672评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,346评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,644评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,700评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,457评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,316评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,706评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,261评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,648评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,859评论 2 335

推荐阅读更多精彩内容