Mac如何在终端用命令批量修改文件名?

avatar
作者
猴君
阅读量:0

1. 场景还原

我们从网上下载的教程文件名中可能会带有视频来源等不相干的信息,使得文件名冗长不便于查看,例如下面的文件,包含一些无用的后缀:

由于这些文件可能分布在很多个文件夹或子文件夹中,一个个手动改肯定不现实,我们需要一个命令快速批量地修改所有文件名。

2. 操作步骤

我们可以使用rename命令批量修改文件名,rename是Linux系统自带的一个命令行工具,用于批量重命名文件。在 macOS 中,默认情况下是没有 rename 命令的,因为 macOS 使用的是 BSD(Berkeley Software Distribution, 伯克利软件发行版, 一个类 Unix 的操作系统) 的变种,而不是 Linux。

我们可以通过安装 Homebrew 这样的软件包管理器来获取 rename 命令,如果已安装请跳过此步骤。

1. 安装Homebrew和rename

安装Homebrew

打开终端或者iterm输入以下命令,按照提示输入密码:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

安装rename

brew install rename

2. 使用find命令筛选出需要修改的文件

find 是一个强大的命令行工具,用于在文件系统中搜索文件和目录。Mac和Linux系统自带find命令,无需安装。find命令很灵活,如果你对find命令不太熟悉,请参考拓展知识根据实际需求筛选出需要修改的文件,下面是一些例子:

例1. 查找当前目录及其子目录下所有mp4文件:

find . -type f -name "*.mp4"

例2. 只查找当前目录所有mp4文件,不查找找子目录中的文件,使用-depth参数:

find . -type f -name "*.mp4" -depth 1

例3. 查找指定目录下及其子目录下所有文件名包含“数字-数字”的文件,使用-regex参数,后面跟正则表达式

find /path/to/search -type f -regex '.*[0-9]-[0-9].*'

3. 使用rename命令批量修改文件名 

关键是将需要修改的内容与正则表达式结合起来,请结合自己的需求修改正则表达式,下面提供一写例子:

例1

我们需要将下面所有mp4文件的"[瑞客论坛][www.ruike1.com]"去掉:

模拟运行

切换到所有文件夹的父目录,运行下面的命令,先模拟运行(防止修改出错)

find . -name "*瑞客*.mp4" -type f -exec rename -v -n 's/\[瑞客论坛]\[www.ruike1.com]//g' {} \;

 下面是这个命令的解释:

find .: 在当前目录及其子目录中搜索文件和目录。

-name "*瑞客*.mp4": 匹配文件名中包含 瑞客 字符串且以 .mp4 结尾的文件。

-type f: 限定搜索结果为普通文件。

-exec rename -v -n 's/\[瑞客论坛]\[www.ruike1.com]//g' {} \;: 对于每个找到的文件执行 rename 命令。{} 表示当前找到的文件名,\; 表示执行命令结束。

rename: 命令行文件重命名工具。

-v: 表示进行详细输出。

-n: 表示执行测试,即显示将要执行的操作但不实际执行

's/\[瑞客论坛]\[www.ruike1.com]//g': 这是 Perl 风格的正则表达式替换。s/old/new/g 表示将字符串中的 old 替换为 newg 表示全局替换。在这个表达式中,我们将 [瑞客论坛][www.ruike1.com] 替换为空,即删除这部分字符串。需要注意的是,正则表达式中的 [  是特殊字符,需要用 \ 进行转义

输出结果检查

输出结果如果包含"would be renamed to",表示正则表达式生效,但修改是否达到预期还要看后面的文件名是否修改正确,如下面的输出内容,表示修改符合我的预期(删除了多余后缀):

如果输出结果包含"unchanged",表示正则表达式与实际需求不符,需要修改正则表达式。 

运行修改 

当上一步的模拟运行达到预期后,或者你确定正则表达式填写无误后,可以去掉-n参数,直接运行修改,请注意,这种修改无法还原

find . -name "*瑞客*.mp4" -type f -exec rename -v 's/\[瑞客论坛]\[www.ruike1.com]//g' {} \;

检查输出结果:

由于加了-v参数,会输出详细步骤,如果你不需要,可去掉该参数运行,然后在访达直接查看修改后的结果。

例2

例如,我还想删除文件名前面多余的序号

运行命令:

find . -name "*.mp4" -exec rename -v 's/\[.*]--//g' {} \;

3. 拓展知识 

find命令

find 命令是一个强大的用于在文件系统中搜索文件和目录的工具,它具有广泛的功能和选项,可以根据各种条件来查找文件,例如文件名、文件类型、文件大小、权限等。下面详细介绍一下 find 命令的用法和常见参数:

基本用法:

find [起始目录] [匹配条件] [动作] 

[起始目录]:指定搜索的起始目录,默认为当前目录。

[匹配条件]:指定要匹配的条件,例如文件名、文件类型、大小等。

[动作]:指定在找到匹配项时要执行的操作,例如打印匹配项、执行其他命令等。

常见参数:

-name pattern:按文件名模式匹配搜索文件。

-type type:指定搜索的文件类型,如 f 表示普通文件,d 表示目录。

-size [+|-]size[unit]:按文件大小搜索,可以使用 +- 来指定大于或小于指定大小的文件,单位可以是 c(字节)、k(KB)、M(MB)、G(GB)等。

-exec command {} \;:对每个找到的文件执行指定的命令,{} 表示匹配到的文件。

-print:打印匹配项的路径。

-delete:删除匹配到的文件。

-regex pattern:  使用的是基于正则表达式的匹配模式,通常是使用 POSIX 扩展的正则表达式语法。这些正则表达式语法与普通的通配符模式(如 -name 参数中使用的 *? 等)相比更加强大和灵活。

-perm mode:  指定要搜索的权限

  • mode:指定要匹配的权限模式。
  • mode 是一个三位数的八进制数,分别表示用户、群组和其他用户的权限。
  • 每个数字的含义分别为:
    • 4:读权限(r)
    • 2:写权限(w)
    • 1:执行权限(x)
  • 若要匹配某种权限,只需将相应的数字相加即可。例如,读写权限为 6,读写执行权限为 7。

 示例

find 命令非常灵活,可以根据我们的需求组合不同的选项来实现各种搜索操作。使用前请确保理解每个选项的含义以及操作的影响。

1. 在当前目录及其子目录中查找所有以 .txt 结尾的文件:

find . -name "*.txt"

2. 在 /usr/bin 目录中查找所有普通文件:

find /usr/bin -type f

3. 在 /home 目录及其子目录中查找大于 1GB 的文件并删除它们:

find /home -size +1G -delete

4. 在 /var/log 目录中查找所有 .log 结尾的文件并将它们复制到 /backup 目录下:

find /var/log -name "*.log" -exec cp {} /backup \;

5. 匹配文件名中包含两个数字之间有一个减号的文件:

find . -regex '.*[0-9]-[0-9].*'

6. 查找当前目录及其子目录中所有拥有读权限但没有写权限的文件:

find . -perm /400 ! -perm /200

rename命令 

rename 命令是用于批量重命名文件的命令行工具。它允许您使用正则表达式来匹配文件名,并通过指定的替换模式来修改文件名。

基本用法:

rename [选项] '正则表达式' 文件名...

[选项]rename 命令支持一些选项,例如 -v(详细输出)、-n(测试模式,不实际重命名文件)、-f(强制执行,忽略警告)等。

'正则表达式':用于匹配文件名的正则表达式模式,可以是 Perl 正则表达式。

文件名...:要重命名的文件名列表。

常用参数:

-v, --verbose:显示详细的输出,即显示哪些文件被重命名成了什么。

-n, --no-act:测试模式,不实际执行重命名操作,而是显示将要执行的重命名操作。这可以帮助您在执行真正的重命名之前进行预览。

-f, --force:强制执行操作,忽略警告。通常在重命名时文件名可能会冲突时使用。

 示例:

1. 使用 -v 参数显示详细输出,将当前目录下所有 .txt 文件的扩展名改为 .bak

rename -v 's/\.txt$/.bak/' *.txt

2. 使用 -n 参数进行测试,将文件名中的空格替换为下划线:

rename -v -n 's/ /_/g' *

3. 在文件名前面添加前缀:

rename 's/^/prefix_/' *

4. 在文件名后面添加后缀:

rename 's/$/_suffix/' *

5. 使用 -f 参数强制执行操作,忽略警告,将当前目录下所有文件名中的大写字母改为小写:

rename -f 'y/A-Z/a-z/' *

 6. 与find命令结合

例如:将 /home/user/documents 目录下所有以 .txt 结尾的文件的扩展名改为 .bak,可以使用 find 命令找到这些文件,然后再结合 rename 命令进行批量重命名。

find /home/user/documents -type f -name "*.txt" -exec rename -v 's/\.txt$/.bak/' {} \;

命令解释:

find /home/user/documents:在 /home/user/documents 目录及其子目录中搜索文件。

-type f:限定搜索结果为普通文件。

-name "*.txt":匹配文件名以 .txt 结尾的文件。

-exec rename -v 's/\.txt$/.bak/' {} \;:对每个匹配到的文件执行 rename 命令,将 .txt 扩展名改为 .bak{} 表示当前找到的文件,\; 表示命令结束。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!