《快乐的 Linux 命令行》
find
find
命令接收一个或多个目录名来执行搜索。
1 2
| $ find Documents/ | wc -l 17905
|
-type d
限制了只搜索目录。
1 2
| $ find Documents/ -type d | wc -l 1741
|
find
命令支持的常见文件类型测试条件:
文件类型 |
描述 |
b |
块特殊设备文件 |
c |
字符特殊设备文件 |
d |
目录 |
f |
普通文件 |
l |
符号链接 |
-name
参数后面跟通配符来根据文件名查找,用双引号
引起来,从而阻止shell
展开路径名。
-size +1M
代表文件大小大于1M
的文件。
1 2 3 4
| $ find Documents/ -type f -name "*.png" | wc -l 512 $ find Documents/ -type f -name "*.png" -size +1M | wc -l 55
|
-size
的常见单位:
字符 |
单位 |
b |
512 个字节块 |
c |
字节 |
w |
两个字节的字 |
k |
千字节(1024 个字节单位) |
M |
兆字节(1048576 个字节单位) |
G |
千兆字节(1073741824 个字节单位) |
测试条件 |
描述 |
-cmin n |
匹配内容或属性最后修改时间正好在n 分钟之前的文件或目录,指定少于n 分钟之前,使用-n ,指定多于n 分钟之前,使用+n |
-cnewer file |
匹配内容或属性最后修改时间晚于file 的文件或目录 |
-ctime n |
匹配内容和属性最后修改时间在n*24 小时之前的文件和目录 |
-empty |
匹配空文件和目录 |
-group name |
匹配属于一个组的文件或目录,组可以用组名 或组ID 来表示 |
-iname pattern |
就像-name 测试条件,但是不区分大小写 |
-inum n |
匹配inode 号是n 的文件 |
-mmin n |
匹配内容被修改于n 分钟之前的文件或目录 |
-mtime n |
匹配的文件或目录的内容被修改 于n*24 小时之前 |
-name pattern |
用指定的通配符模式匹配的文件和目录 |
-newer file |
匹配内容晚于指定的文件的文件和目录 |
-nouser |
匹配不属于一个有效用户的文件和目录 |
-nogroup |
匹配不属于一个有效的组的文件和目录 |
-perm mode |
匹配权限已经设置为指定的mode 的文件或目录,mode 可以用八进制 或符号表示法 |
-samefile name |
类似于-inum 测试条件,匹配和文件name 享有同样inode 号的文件 |
-size n |
匹配大小为n 的文件 |
-type c |
匹配文件类型是c 的文件 |
-user name |
匹配属于某个用户的文件或目录,这个用户可以通过用户名 或用户ID 来表示 |
多个测试条件的连接符号:
操作符 |
描述 |
-and |
如果操作符两边的测试条件都是真,则匹配。可以简写为-a ,若没有使用操作符,则默认使用-and |
-or |
若操作符两边的任一个测试条件为真,则匹配。可以简写为-o |
-or |
若操作符两边的任一个测试条件为真,则匹配。可以简写为-o |
-not |
若操作符后面的测试条件是假,则匹配。可以简写为一个感叹号! |
() |
把测试条件和操作符组合起来形成更大的表达式 |
find
命令允许基于搜索结果来执行操作:
操作 |
描述 |
-delete |
删除当前匹配的文件 |
-ls |
对匹配的文件执行等同的ls -dils 命令 |
-print |
把匹配文件的全路径名输送到标准输出。如果没有指定其它操作,这是默认操作 |
-quit |
一旦找到一个匹配,退出 |
find
命令也可以调用任意命令:
{}
是当前路径名的符号表示。
因为花括号和分号对于shell
有特殊含义,所以它们必须被引起来或被转义:
通过使用-ok
行为来代替-exec
,在执行每个指定的命令之前,会提示用户。
通过把末尾的分号改为加号,就激活了find
命令的一个功能,把搜索结果结合为一个参数列表,然后用于所期望的命令的一次执行。
1 2 3
| find Documents/ -type f -name '*.bak' -exec ls -l '{}' ';'
find Documents/ -type f -name '*.bak' -exec ls -l '{}' '+'
|
测试
1 2
| mkdir -p playground/dir-{00{1..9},0{10..99},100} touch playground/dir-{00{1..9},0{10..99},100}/file-{A..Z}
|
1
| find playground -type f -name 'file-A'
|
不同于ls
命令,find
命令的输出结果是无序的,其顺序由存储设备的布局决定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| $ touch playground/timestamp $ stat playground/timestamp File: playground/timestamp Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 811h/2065d Inode: 106302168 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/ hs) Gid: ( 1000/ hs) Access: 2021-04-08 22:33:03.175222042 +0800 Modify: 2021-04-08 22:33:03.175222042 +0800 Change: 2021-04-08 22:33:03.175222042 +0800 Birth: -
$ touch playground/timestamp $ stat playground/timestamp File: playground/timestamp Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 811h/2065d Inode: 106302168 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/ hs) Gid: ( 1000/ hs) Access: 2021-04-08 22:36:02.113310036 +0800 Modify: 2021-04-08 22:36:02.113310036 +0800 Change: 2021-04-08 22:36:02.113310036 +0800 Birth: -
|
1
| find playground -type f -name 'file-B' -exec touch '{}' ';'
|
1
| find playground -type f -newer playground/timestamp
|
1
| find playground \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \) | sort
|
1
| find playground \( -type f -not -perm 0600 -exec chmod 0600 '{}' ';' \) -or \( -type d -not -perm 0711 -exec chmod 0700 '{}' ';' \)
|