find 是一条递归命令,用于在一个目录中搜索符合条件的文件(或目录),然后对选定的文件执行某些操作。
find search_path selection_criteria action
Section 17.1: 按名称或扩展名搜索文件
查找与 pwd 相对的特定名称的文件/目录:
$ find . -name "myFile.txt"
./myFile.txt
要查找具有特定扩展名的文件/目录,请使用通配符:
$ find . -name "*.txt"
./myFile.txt
./myFile2.txt
要查找与许多扩展名之一匹配的文件/目录,可以使用通配符:
$ find . -name "*.txt" -o -name "*.sh"
查找名称以 abc 开头并以一个字母结尾的文件/目录:
$ find . -name "abc[a-z][0-9]"
查找特定目录下的所有文件/目录
$ find /opt
只搜索文件(不搜索目录),使用 -type f:
find /opt -type f
只搜索目录(不搜索普通文件),使用 -type d:
find /opt -type d
Section 17.2: 针对找到的文件执行命令
有时,我们需要针对大量文件运行命令。这可以使用 xargs 来完成。
find . -type d -print | xargs -r chmod 770
上述命令将递归查找相对于 .(即当前工作目录)的所有目录(-type d),并执行chmod 770。如果 find 没有找到任何文件,-r 选项会指定 xargs 不运行 chmod。
如果文件名或目录中有空格符,该命令可能会卡住;解决方法是使用下面的命令
find . -type d -print0 | xargs -r -0 chmod 770
在上例中,"-print0" 和 "-0" 选项会指定使用空字节分隔文件名,并允许在文件名中使用空格等特殊字符。这是 GNU 扩展,在其他版本的 find 和 xargs 中可能无法使用。
find . -type d -exec chmod 770 {} \;
在这里,"{}" 是一个占位符,表示你想在该处使用文件名。find 将对每个文件单独执行 chmod。
您也可以将所有文件名传递给 chmod 的单次调用,方法是使用
find . -type d -exec chmod 770 {} +
这也是上述 xargs 代码段的行为。(要单独调用每个文件,可以使用 xargs -n1)。
第三种方法是让 bash 循环查找文件列表中的输出:
find . -type d | while read -r d; do chmod 770 "$d"; done
这在语法上最是笨拙的使用,但当你想在每个找到的文件上运行多个命令时却很方便。
不过,面对名称奇特的文件名,这种方法并不安全。
find . -type f | while read -r d; do mv "$d" "${d// /_}"; done
上面的代码将用下划线替换文件名中的所有空格(如果前导目录名中有空格,此示例也不起作用)。
上述方法的问题在于,"while read -r" 希望每行一个条目,但文件名可能包含换行符(而且,“read -r ”会丢失任何尾部空白)。你可以通过回转来解决这个问题:
find . -type d -exec bash -c 'for f; do mv "$f" "${f// /_}"; done' _ {} +
这样,"-exec" 以完全正确和可移植的形式接收文件名;"bash -c" 则以若干参数的形式接收文件名,这些参数将在 "$@" 中找到,并正确地加上引号等(当然,脚本需要正确处理这些文件名;每个包含文件名的变量都需要加上双引号)。
神秘的 _ 是必要的,因为 bash -c 'script' 的第一个参数用于填充 $0。
Section 17.3: 按访问/修改时间查找文件
在 ext 文件系统中,每个文件都存储了与之相关的访问、修改和(状态)更改时间,要查看这些信息,可以使用 stat myFile.txt;使用 find 中的时间选项,我们可以搜索在特定时间范围内修改的文件。
要查找在过去 2 小时内修改过的文件,请执行以下操作
$ find . -mmin -120
查找最近 2 小时内未被修改的文件:
$ find . -mmin +120
The above example are searching only on the modified time - to search on access times, or changed times, use a, or c accordingly.
上述示例仅搜索 modified (修改)时间,如果要搜索 access (访问)时间或 changed (更改)时间,请相应使用 a 或 c 。
$ find . -amin -120
$ find . -cmin +120
格式如下:
-mmin n: 文件在 n 分钟前被修改-mmin -n: 文件在少于 n 分钟前被修改-mmin +n: 文件在 n 分钟前被修改过
查找最近 2 天内修改过的文件:
find . -mtime -2
查找最近 2 天内未修改的文件
find . -mtime +2
使用-atime和-ctime分别表示访问时间和状态更改时间。
格式如下:
-mtime n : 文件在 24 小时前被修改
-mtime -n : 文件在少于 24 小时前被修改
-mtime +n : 文件在 24 小时前被修改过
查找在 2007-06-07 至 2007-06-08 的 日期范围 内修改的文件:
find . -type f -newermt 2007-06-07 ! -newermt 2007-06-08
查找在一系列时间戳中访问过的文件(使用文件作为时间戳),从 1 小时前到 10 分钟前:
touch -t $(date -d '1 HOUR AGO' +%Y%m%d%H%M.%S) start_date
touch -t $(date -d '10 MINUTE AGO' +%Y%m%d%H%M.%S) end_date
timeout 10 find "$LOCAL_FOLDER" -newerat "start_date" ! -newerat "end_date" -print
格式如下:
-newerXY reference: 将当前文件的时间戳与 reference 进行比较。XY可以是以下值之一:at(访问时间)、mt(修改时间)、ct(更改时间)等。reference是要与指定时间戳(访问、修改、更改)进行比较的文件名或描述绝对时间的字符串。
Section 17.4: 根据大小查找文件
查找大于 15MB 的文件:
find -type f -size +15M
查找小于 12KB 的文件:
find -type f -size -12k
查找大小正好为 12KB 的文件:
find -type f -size 12k
Or
find -type f -size 12288c
Or
find -type f -size 24b
Or
find -type f -size 24
格式如下:
find [options] -size n[cwbkMG]
查找 n 块大小的文件,其中 +n 表示大于 n 块,-n 表示小于 n 块,n(不含任何符号)表示正好是 n 块
区块大小单位:
- c: bytes
- w: 2 bytes
- b: 512 bytes (default)
- k: 1 KB
- M: 1 MB
- G: 1 GB
Section 17.5: 过滤路径
-path 参数允许指定一个模式来匹配结果的路径。该模式也可以匹配名称本身。
只查找路径(文件夹或名称)中包含 log 的文件:
find . -type f -path '*log*'
只查找名为 log 的文件夹内的文件(任何含log的路径):
find . -type f -path '*/log/*'
只查找名为 log 或 data 的文件夹中的文件:
find . -type f -path '*/log/*' -o -path '*/data/*'
查找除名为 bin 的文件夹中的文件外的所有文件:
find . -type f -not -path '*/bin/*'
查找除 bin 文件夹或日志文件以外的所有文件:
find . -type f -not -path '*log' -not -path '*/bin/*'
Section 17.6: 按类型查找文件
要查找文件,请使用 -type f 标志
$ find . -type f
要查找目录,使用 -type d 标志
$ find . -type d
要查找块设备,使用 -type b 标志
$ find /dev -type b
要查找符号链接,使用 -type l 标志
$ find . -type l
Section 17.7: 按特定扩展名查找文件
要查找当前路径下所有具有特定扩展名的文件,可以使用下面的 find 语法。它通过使用 bash 内置的 glob 结构来匹配所有带有.extension的文件名。
find /directory/to/search -maxdepth 1 -type f -name "*.extension"
要查找当前目录中所有类型为.txt的文件,请执行
find . -maxdepth 1 -type f -name "*.txt"