Linux技巧:find 命令简单入门介绍和问题点解析( 六 )


如这个帮助说明所举的例子,一般常用这个表达式来匹配特定后缀名的文件 。具体举例如下 。
匹配单个后缀名下面是匹配单个后缀名的例子:
$ find . -name '*.c'./src/main.c可以看到,find . -name '*.c' 命令打印出所有后缀名为 .c 的文件名 。
注意 *.c 要用引号括起来,避免 bash 当 * 号当成通配符处理 。
该命令相当于 find . -name '*.c' -and -print,只有 -name '*.c' 表达式返回为 true 的文件名才会执行到 -print 表达式,打印出该文件名 。
注意:使用 -name pattern 表达式并不表示只查找符合 pattern 模式的文件,find 命令还是会查找出所给目录的所有文件,并把每个文件名依次传给后面的表达式进行评估,只有符合 -name pattern 表达式的文件名才会返回 true,才会被打印出来 。
不符合这个表达式的文件也会被查找到,只是没有打印出来而已 。
匹配多个后缀名下面是匹配多个后缀名的例子:
$ find . -name '*.c' -o -name '*.am'./src/main.c./Makefile.am$ find . ( -name '*.c' -o -name '*.am' ) -and -print./src/main.c./Makefile.am$ find . -name '*.c' -o -name '*.am' -and -print./Makefile.am可以看到,find . -name '*.c' -o -name '*.am' 命令打印出所有后缀名为 .c 和 .am 的文件名 。
该命令相当于 find . ( -name '*.c' -o -name '*.am' ) -and -print,而不是相当于 find . -name '*.c' -o -name '*.am' -and -print,后者只能打印出后缀名为 .am 的文件名 。
前面也有说明,find 命令会对所有返回为 true 的文件名默认执行 -print 表达式,这个返回为 true 是手动提供的整个表达式的判断结果 。
也就是说手动提供的整个表达式应该会用小括号括起来,组成独立的表达式,再跟默认添加的 -and -print 表达式组合成新的表达式,避免直接加上 -and -print 后,会受到操作符优先级的影响,打印结果可能不符合预期 。
重新格式化要打印的文件名信息除了使用 -print 表达式打印文件名之外,也可以使用 -printf 表达式格式化要打印的文件名信息 。
这是一个 action 类型表达式,GNU find 在线帮助手册对该表达式的说明如下:

Action: -printf format
True; print format on the standard output, interpreting ‘’ escapes and ‘%’ directives.
Field widths and precisions can be specified as with the printf C function.
Unlike ‘-print’, ‘-printf’ does not add a newline at the end of the string. If you want a newline at the end of the string, add a ‘n’.
即,-printf 表达式使用类似于C语言 printf 函数的写法来格式化要打印的信息,支持的一些格式如下:
  • %pFile’s name.这个格式包含完整路径的文件名 。
  • %fFile’s name with any leading directories removed (only the last element).这个格式只包含文件名,会去掉目录路径部分 。
注意:-printf 是 action 类型表达式,前面提到,如果提供除了 -prune 之外的 action 类型表达式,将不会自动添加 -print 表达式 。
加了 -printf 表达式将由该表达式来决定打印的文件信息 。
使用 -printf 表达式的例子如下:
$ find . ( -name '*.c' -o -name '*.am' ) -printf "%ft%pn"main.c./src/main.cMakefile.am./Makefile.am可以看到,所给 find 命令打印出指定后缀的文件名本身、以及完整路径的文件名 。
-name '*.c' -o -name '*.am' 表达式需要用小括号括起来,组成独立的表达式 。
如果不加小括号,由于 -and 操作符优先级高于 -o 操作符,-name '*.am' 实际上是跟 -printf 表达式组合,后缀名为 .c 的文件名无法执行到 -printf 表达式,将不会打印这些文件名 。
由于 -printf 表达式不会在末尾自动加上换行符,想要换行的话,需要在格式字符串里面加上 ‘n’ 换行符 。
使用正则表达式匹配完整路径文件名在 find 命令里面,-path pattern 表达式和 -name pattern 表达式都是使用通配符来匹配模式,如果想要用正则表达式进行匹配,可以使用 -regex expr 表达式 。
这是 test 类型表达式,GNU find 在线帮助手册对该表达式的说明如下:
-regex expr
True if the entire file name matches regular expression expr. This is a match on the whole path, not a search.
As for ‘-path’, the candidate file name never ends with a slash, so regular expressions which only match something that ends in slash will always fail.


推荐阅读