2.4 文件查找与文件列表

《Linux Shell 脚本攻略(第 2 版)》读书笔记

find 命令工作方式:沿着文件层次结构向下遍历,匹配符合条件的文件,执行相应的操作。

$ find . -print
# 打印文件和目录列表
  • . 指定当前目录
  • -print 指明打印出匹配文件的文件名(路径)。此时将使用 \n 作为输出文件名之间的定界符。此项可以不写,也能打印。
  • -print0 指明使用 \0 作为输出文件名之间的定界符。

1. 根据文件名或正则表达式进行搜索

  • -name 指定文件名所必须匹配的字符串

    $ find . -name "*.txt" -print
    # 查找当前目录下所有以 .txt 结尾的文件名
    
  • -iname 同上,但会忽略字母大小写

  • -o OR 条件操作,匹配多个条件中的一个

    $ find . \( -name "*.txt" -o -name "*.pdf" \) -print
    # 查找当前目录下所有的 .txt 和 .pdf 文件
    
  • -path 匹配文件路径

    $ find . -path "*/source/*" -print
    # 匹配当前目录下所有 source 子目录
    
  • -regex 正则表达式

    $ find . -regex ".*\(\.py\|\.sh\)$"
    # 查找当前目录下所有 .py 和 .sh 文件
    
  • -iregex 同上,但忽略大小写

2. 否定参数

$ find . ! -name "*.txt" -print
# 查找当前目录下所有不以 .txt 结尾的文件

3. 基于目录深度的搜索

  • -maxdepth 指定查找目录的最大深度。
$ find . -maxdepth 1 -name "f*" -print
# 查找当前目录下的所有文件名以 f 开始的文件。不查找子目录。
  • -mindepth 指定开始遍历的最小深度。
$ find . -mindepth 3 -name "f*" -print
./dir1/dir2/file1
./dir3/dir4/f2
# 即使当前目录或 dir1 和 dir3 中包含文件,它们也不会被打印出来。

-maxdepth-mindepthe 应该作为 find 的第三个参数出现。如果作为第四个或之后的参数,就可能会影响到 find 的效率,因为它不得不进行一些不必要的检查。

4. 根据文件类型搜索

-type 可以指明特定的文件匹配类型。
如只列出所有的目录:

find . -type d -print
文件类型 类型参数
普通文件 f
符号链接 l
目录 d
字符设备 c
块设备 b
套接字 s
FIFO p

5. 根据文件时间进行搜索

Unix/Linux 文件系统中的每一个文件都有三种时间戳:

  • 访问时间-atime):用户最近一次访问文件的时间。
  • 修改时间-mtime):文件内容最后一次被修改的时间。
  • 变化时间-ctime):文件元数据(例如权限或所有权)最后一次改变的时间。

在 Unix 中并没有所谓“创建时间”的概念。

以天数为单位进行搜索

-atime-mtime-ctime 用整数值指定,单位是

  • 打印处最近 7 天内被访问过的所有文件:
find . -type f -atime -7 -print
  • 打印出恰好在 7 天前被访问过的所有文件:
find . -type f -atime 7 -print
  • 打印出访问时间超过 7 天的所有文件:
find . -type f -atime +7 -print

以分钟为单位进行搜索

-amin-mmin-cmin 用整数值指定,单位是分钟

打印出访问时间超过 7 分钟的所有文件:

find . -type f -amin +7 -print

以参考文件进行搜索

-newer 指定一个用于比较时间戳的参考文件,然后找出比参考文件更新的(更近的修改时间)所有文件。

找出比 file.txt 修改时间更近的所有文件:

find . -type f -newer file.txt -print

6. 基于文件大小的搜索

$ find . -type f -size +2k
# 大于2KB的文件

$ find . -type f -size -2k
# 小于2KB的文件

$ find . -type f -size 2k
# 等于2KB的文件

可用文件大小单元:

  • c 字节
  • w 字(2 字节)
  • b 块(512 字节)
  • k 1024 字节
  • M 1024k 字节
  • G 1024M 字节

7. 删除匹配的文件

$ find . -type f -name "*.txt" -delete
# 删除当前目录下所有 .txt 文件

8. 基于文件权限和所有权的匹配

$ find . -type f -perm 644 -print
# 打印出权限为 644 的文件
$ find . -type f -user sky -print
# 打印出用户 sky 拥有的所有文件

9. 利用 find 执行命令或动作

$ find . -type f -user root -exec chown sky {} \;
# 将当前目录下所有 root 用户文件的文件所有权改成 sky 用户

# 对于每一个匹配的文件,`{}`会被替换成相应的文件名
# 如果希望使用文件列表作为命令参数,可以在 exec 中使用 `+` 来代替 `;`
$ find . -type f -name "*.c" -exec cat {} \;> all_c_files.txt
# 将当前目录下的所有C程序文件拼接起来写入单个文件 all_c_files.txt
# 因为 find 命令的全部输出就只有一个数据流(stdin),所以只需要使用 `>` 操作符

-exec 结合多个命令

我们无法在 -exec 参数中直接使用多个命令。但是可以把多个命令写到一个 shell 脚本中,然后在 -exec 中使用这个脚本:

-exec ./commands.sh {} \;

10. 让 find 跳过特定的目录

$ find . \( -name ".git" -prune \) -o \( -type f -print \)
# 打印出不包括在 .git 目录中的所有文件的名称(路径)

你可能感兴趣的:(2.4 文件查找与文件列表)