如何在 macOS 终端中批量重命名文件?

Posted

技术标签:

【中文标题】如何在 macOS 终端中批量重命名文件?【英文标题】:How to Batch Rename Files in a macOS Terminal? 【发布时间】:2014-07-28 23:19:35 【问题描述】:

我有一个包含一系列文件的文件夹:

prefix_1234_567.png
prefix_abcd_efg.png

我想批量删除一个下划线和中间的内容,所以输出是:

prefix_567.png
prefix_efg.png

相关但不完全解释:

How can I batch rename files using the Terminal? Regex to batch rename files in OS X Terminal

【问题讨论】:

看看 NSString 和 NSMutableString 的 range 和 substring 方法 您是否考虑过非终端解决方案? Automator 工作流程可以轻松执行这些类型的操作。您可以创建一个自动化工作流程来重命名所有文件并将文本替换为 _*_ 并用空格替换。 我认为 automator 不能做通配符 【参考方案1】:

由于以编程方式重命名文件是有风险的(如果弄错了可能会造成破坏),我会使用专门为批量重命名而构建的具有空运行模式的工具,例如renamer.

此命令对当前目录中的所有文件进行操作,使用--dry-run 直到您确信输出看起来正确:

$ renamer --find "/(prefix_)(\w+_)(\w+)/" --replace "$1$3" -e name --dry-run *

Dry run

✔︎ prefix_1234_567.png → prefix_567.png
✔︎ prefix_abcd_efg.png → prefix_efg.png

Rename complete: 2 of 2 files renamed.

更多重命名器用法示例here。

【讨论】:

【参考方案2】:

你可以使用 sed:

ls * | sed -e 'p;s@_.*_@_@g' | xargs -n2 mv

结果:

prefix_567.png prefix_efg.png

*要先进行试运行,请将末尾的mv 替换为echo

解释:

e:仅 1 个 sed 命令可选。 p:将输入打印到 sed,在这种情况下,它将是任何重命名之前的原始文件名 @: 是 / 字符的替换,以使 sed 更具可读性。也就是说,不要使用 sed s/search/replace/g,而是使用 s@search@replace@g _.* :下划线是一个转义字符,用于引用实际的 '.'字符零次或多次(与正则表达式中的任何字符相反) -n2:表示有2个输出需要作为参数传递给mv。对于来自 ls 的每个输入,此 sed 命令将生成 2 个输出,然后将其提供给 mv。

【讨论】:

聪明,虽然有点神秘的解决方案。使其更通用,以便也支持带有嵌入空格的文件名,变得更加神秘:ls * | xargs -I % bash -c 'echo mv "%" "$(sed 's@_.*_@_@' <<<"%")"'(删除 echo 以实际重命名)。【参考方案3】:

在您的具体情况下,您可以使用以下bash 命令(bash 是 macOS 上的默认 shell):

for f in *.png; do echo mv "$f" "$f/_*_/_"; done

注意:如果您的文件名有可能以- 开头,请将-- 放在它们之前[1]:mv -- "$f" "$f/_*_/_"

注意:echo 被添加到 mv 之前,以便执行空运行。删除它以执行实际重命名。

您可以从命令行运行它或在脚本中使用它。

"$f/_*_/_"bash parameter expansion 的应用:(第一个)子字符串匹配模式 _*_ 被替换为文字 _,有效地从名称中删除了中间标记。 注意_*_ 是一个模式(通配符表达式,也用于通配符),而不是正则表达式(要了解模式,请运行@987654338 @ 并搜索 Pattern Matching)。

如果您发现自己经常批量重命名文件,考虑安装一个专门的工具,例如基于 Perl 的 rename utility。 在 macOS 上,您可以使用流行的包管理器 Homebrew 安装它,如下所示:

brew install rename

这相当于顶部使用rename的命令:

rename -n -e 's/_.*_/_/'  *.png

同样,这个命令执行一次试运行;删除 -n 以执行实际重命名。

类似于bash 解决方案,s/.../.../ 执行文本替换,但 - 与 bash 不同 - 使用了真正的正则表达式

[1] 大多数实用程序支持的特殊参数-- 的目的是表明后续参数应被视为操作数(值),即使它们看起来options,因为以 - 开头,如 Jacob C. 注释。

【讨论】:

很好的答案,效果很好。我也很感激您返回并对其进行了编辑以进行更多解释,并在我重复此操作时提供更优雅的解决方案。再次,非常感谢,非常有帮助 使用匹配替换的示例 (.* -> $1),例如将Foo bar S01E01 biz baz.ext 重命名为S01E01.extrename -n -e 's/.*(S[0-9]2E[0-9]2).*(\.[a-z]2,4)/$1$2/' * 喜欢使用echo 进行试运行的想法。感谢您的提示! 强烈建议只做brew install rename【参考方案4】:

试试这个

for i in *.png ; do mv "$i" "$i/remove_me*.png/.png" ; done

这是另一种方式:

for file in Name*.png; do mv "$file" "01_$file"; done

【讨论】:

【参考方案5】:

使用mmv

mmv '*_*_*' '#1_#3' *.png

【讨论】:

鉴于这是 OS X,正确的安装过程是 brew install mmv【参考方案6】:

您可以使用brew 安装rename 命令。只需执行brew install rename 并使用它。

【讨论】:

【参考方案7】:

要重命名文件,您可以使用rename 实用程序:

brew install rename

例如,更改当前目录中所有文件名中的搜索字符串:

rename -nvs searchword replaceword *

删除“n”参数以应用更改。

更多信息:man rename

【讨论】:

OS X 版本的GNU bash (x86_64-apple-darwin) 不包括重命名实用程序。 谢谢,是的,它需要通过brew install rename安装 这个技巧太棒了!我输入了rename -vs GLYCOPHORIN GLYCC *,现在它会自动重命名 450 多个文件。而且速度也超级快。 太棒了!喜欢在它实际重命名之前的“显示将要更改的内容”部分! 您也可以使用正则表达式。重命名 's/123/onetwothree/g' *【参考方案8】:

我有一批看起来像这样的文件:be90-01.png 并且需要将破折号更改为下划线。我用过这个,效果很好:

for f in *; do mv "$f" "`echo $f | tr '-' '_'`"; done

【讨论】:

以上是关于如何在 macOS 终端中批量重命名文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何用Matlab为文件批量重命名

Bat批处理:批量重命名包含指定名称文件夹里的指定文件

在git中将文件批量重命名为小写

如何批量在多个文件前面添加名称或者数字?

正则表达式批量重命名 OS X 终端中的文件

如何批量重命名带有序列号的照片文件夹中的文件