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


123

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

prefix_1234_567.png
prefix_abcd_efg.png

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

prefix_567.png
prefix_efg.png

相关但不完全解释:


看一下NSString和NSMutableString的范围和子字符串方法
Grady Player

1
您是否考虑过非终端解决方案?Automator工作流程可以轻松执行这些类型的操作。您可以创建一个自动工作流程来重命名所有文件,并用_*_空白替换文本。
2014年

我以为
自动化器

Answers:


234

在特定情况下,可以使用以下bash命令(bashmacOS上的默认外壳):

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

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

注:echo前置到mv以进行试运行。删除它以执行实际的重命名。

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

  • "${f/_*_/_}"bash 参数扩展的一种应用:(第一个)子字符串匹配模式_*_被文字替换_,有效地从名称中删除了中间标记。
  • 请注意,这_*_是一个模式(通配符表达式,也用于通配符),而不是正则表达式(以了解模式,运行man bash并搜索Pattern Matching)。

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

brew install rename

这等效于顶部使用的命令rename

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

同样,此命令执行空运行;删除-n以执行实际的重命名。

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

[1] --大多数实用程序支持的特殊参数的用途是,表示应将后续参数视为操作数(值),即使它们由于以开头而看起来选项一样-,如Jacob C.所述


3
很好的答案,效果很好。我也很感谢您回过头来对其进行编辑以进一步说明它,如果我再重复一次,则可以提供一个更优雅的解决方案。再次非常感谢,非常有帮助
kidnim 2014年

4
使用匹配替换(.*-> $1)的示例,例如,重命名Foo bar S01E01 biz baz.extS01E01.extrename -n -e 's/.*(S[0-9]{2}E[0-9]{2}).*(\.[a-z]{2,4})/$1$2/' *
Steve Robbins

2
喜欢echo用于空运行的想法。谢谢你的提示!
James Wright

强烈建议您做brew install rename
克里斯·雷德福

98

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

brew install rename

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

rename -nvs searchword replaceword *

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

更多信息: man rename


1
OS XGNU bashx86_64-apple-darwin)版本不包含重命名实用程序。
l'l'l

4
谢谢,是的,它需要通过安装brew install rename
David Thomas

2
这个技巧很棒!我输入了rename -vs GLYCOPHORIN GLYCC *,现在它会自动重命名450多个文件。而且超级快。
桑德·范德兰

3
优秀的!在实际上重命名事物之前,请喜欢“显示将要更改的部分”部分!
本·达芬

3
您也可以使用正则表达式。重命名's / 123 / onetwothree / g'*
Bryan

12

您可以使用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。

1
聪明的解决方案。使它更通用,以便还支持带有嵌入式空格的文件名,变得更加不可思议:(ls * | xargs -I % bash -c 'echo mv "%" "$(sed 's@_.*_@_@' <<<"%")"'删除echo实际重命名)。
mklement0 2014年

2
奥术?我喜欢这个!
比拉勒·阿基尔

7

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

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



1

试试这个

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

这是另一种方式:

for file in Name*.png; do mv "$file" "01_$file"; done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.