File Searching
locate
:通过名字查找文件
1 | locate [OPTION]... [PATTERN]... |
locate
程序会快速地搜索其内部的路径名数据库,然后输出每个绝对路径中包含了[PATTERN]
的文件的绝对路径。[PATTERN]
一般为普通的字符串,但有些版本还会包括正则表达式匹配和通配符匹配。
1 | [meme@localhost Playground]# locate bin/zip |
locate
的路径名数据库由updatedb
程序创建。该程序会在特定的时间间隔(如每次开机)被守护进程cron
执行,因此一些新创建的文件可能无法用locate
进行搜索,但是我们也可以以超级用户的身份手动运行updatedb
:
1 | [root@localhost Playground]# updatedb |
find
:在目录层次结构中搜索文件
1 | find [path...] [expression] |
locate
可以让我们简单地用文件名找到文件的位置,而find
则可以让我们在指定的目录[path]
(绝对或相对路径)下,用文件的各种属性匹配相应的文件。在了解find
之前,我们先在当前目录下创建100个子目录,并在每个子目录下创建24个普通文件:
1 | [meme@localhost Playground]$ mkdir dir-{00{1..9},0{10..99},100} |
在最基本的用法里,find
会输出所查目录及其子目录的所有文件的路径,其中,相对路径查找输出相对路径,绝对路径查找则输出绝对路径:
1 | [meme@localhost Playground]$ find ./dir-001 |
Tests:测试条件
find
拥有众多的测试条件,每个测试条件都一定程度上对应着文件的一项属性。find
在指定目录中遍历文件元数据时,会使用用户指定的测试条件来筛选文件。
-type
-type
选择文件的类别:b
块设备文件、c
字符设备文件、d
目录、f
普通文件、l
符号链接:
1 | [meme@localhost Playground]$ find ./dir-001 -type f |
-name
-name
选择文件的名字。此处的名字只是名字,而不包含路径:
1 | [meme@localhost Playground]$ find ./dir-001 -name '*1' |
-size
-size
选择文件的大小,后面跟着的字符串,+1M
表示只选择大于1M的文件,-1M
表示只选择小于1M的文件,1M
表示只选择大小等于1M的文件:
1 | [meme@localhost Playground]$ find ./dir-001 -size '1M' |
其他
除了上面这三个常用的测试条件,find
还支持很多其他的测试条件,如-perm mode
选择指定权限mode
的文件等。
Operators:操作符
find
的测试条件实际上相当于程序语言中的条件语句,因此,它很自然地也能支持各种条件语句的逻辑组合。这些组合与编程语言中的一样,通过逻辑操作符与-and
、或-or
、非-not
来实现。这些逻辑操作符的运算逻辑和执行特性和一般程序语言中的没有任何区别。通常地,逻辑操作符连接的两个测试条件应该分别用()
括起来。在命令行中,()
有特殊的意义,因此实际上要为()
加上转义字符,即实际应使用\(\)
。
-and
:find
的默认操作符,即若测试条件之间没有操作符,那么其连接符号默认是-and
。1
2
3
4[meme@localhost Playground]$ find . -type f -name '*A'
./dir-001/file-A
...
./dir-100/file-A上面两个命令是等价的。1
2
3
4[meme@localhost Playground]$ find . \( -type f \) -and \( -name '*A' \)
./dir-001/file-A
...
./dir-100/file-A-or
:表或,用法与-and
相同。-not
:表非,用在想要取非的测试条件之前。1
2[meme@localhost Playground]$ find ./dir-001 -not -type f
./dir-001
Actions:行为
find
允许用户对筛选结果立即进行操作,即,将筛选结果作为其他命令的输入参数。
-delete
:删除当前匹配到的文件;-ls
:对当前匹配到的文件执行ls
操作;-print
:将当前匹配文件的路径打印出来,是find
的默认操作;-quit
:一旦找到一个匹配项就退出。
以上四个是find
内部自带的操作,如-delete
:
1 | [meme@localhost Playground]$ find ./dir-001 -type f -delete |
需要注意的是,
Tests
和Actions
在find
看来是同优先级的,而find
又是顺序过滤的,因此不同的Tests
和Actions
的顺序很重要。
用户自定义行为
除了find
自带的这几种行为,find
还允许用户自由地使用所有合法的Linux命令,一般的格式为:
1 | -exec [command] '{}' ';' |
因为
{}
和;
在命令行中有特殊意义,所以必须被引用为字符串或者转义。
如,对筛选出来的文件使用rm -r
操作:
1 | [meme@localhost Playground]$ find . -name '*1' |
有时为了安全起见,我们会想要一个个地确认Actions
的效果,此时我们可以使用-ok
来代替-exec
。使用-ok
后,[command]
在执行前会先向用户进行确认:
1 | [meme@localhost Playground]$ find . -name '*2' -ok rm -r '{}' ';' |
当我们使用';'
时,我们在告诉find
:对于每一个匹配的文件,运行一次[command]
,这样会导致当匹配结果有$n$个文件时,[command]
被运行$n$次。要想避免这种情况,我们可以将';'
替换为+
,这样就是在告诉find
:将所有的结果合成一个列表再执行命令:
1 | [meme@localhost Playground]$ find . -name '*2' -exec rm -r '{}' + |
注意,此时只能用
-exec
而不能用-ok
。
辅助命令
有许多的辅助命令能够让locate
和find
的功能更强大。
xargs
1 | xargs [OPTION]... COMMAND INITIAL-ARGS... |
xargs
从标准输入中接受输入,并将输入转换为一个命令行参数列表,这个参数列表可以直接作为其他指令的参数,如:
1 | [meme@localhost Playground]$ find . -name '*13' |
xargs
将./dir-013
管道为了ls -l
的命令行参数。
touch
1 | touch [OPTION]... FILE... |
当touch
后的文件不存在时,touch
相当于一个创建文件操作:
1 | [meme@localhost Playground]$ locate taylor |
若文件已存在,则touch
会将其修改时间设置为当前时间:
1 | [meme@localhost Playground]$ stat taylor |
stat
相当于加强版的ls
。