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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24102974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:52:25  来源:igfitidea点击:

How to Batch Rename Files in a macOS Terminal?

bashmacosshellterminalfile-rename

提问by kidnim

I have a folder with a series of files named:

我有一个文件夹,其中包含一系列名为:

prefix_1234_567.png
prefix_abcd_efg.png

I'd like to batch removeone underscore and the middle content so the output would be:

我想批量删除一个下划线和中间内容,因此输出将是:

prefix_567.png
prefix_efg.png

Relevant but not completely explanatory:

相关但不完全解释:

回答by mklement0

In your specific case you can use the following bashcommand (bashis the default shell on macOS):

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

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

Note: If there's a chance that your filenames start with -, place --before them[1]:
mv -- "$f" "${f/_*_/_}"

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

Note: echois prepended to mvso as to perform a dry run. Remove it to perform actual renaming.

注意:echo预先添加到mv以便执行试运行。删除它以执行实际重命名。

You can run it from the command line or use it in a script.

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

  • "${f/_*_/_}"is an application of bashparameter expansion: the (first) substring matching pattern _*_is replaced with literal _, effectively cutting the middle token from the name.
  • Note that _*_is a pattern(a wildcard expression, as also used for globbing), not a regular expression(to learn about patterns, run man bashand search for Pattern Matching).
  • "${f/_*_/_}"bash参数扩展的应用:(第一个)子字符串匹配模式_*_被替换为字面量_,有效地从名称中删除了中间标记。
  • 请注意,这_*_是一个模式(通配符表达式,也用于通配符),而不是正则表达式(要了解模式,运行man bash并搜索Pattern Matching)。


If you find yourself batch-renaming files frequently, consider installing a specialized tool such as the Perl-based renameutility. On macOS you can install it using popular package manager Homebrewas follows:

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

brew install rename

Here's the equivalent of the command at the top using rename:

这是使用顶部的命令的等效项rename

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

Again, this command performs a dry run; remove -nto perform actual renaming.

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

  • Similar to the bashsolution, s/.../.../performs text substitution, but - unlike in bash- true regular expressionsare used.
  • bash解决方案类似,s/.../.../执行文本替换,但 - 与 in bash- true正则表达式不同。


[1] The purpose of special argument --, which is supported by most utilities, is to signal that subsequent arguments should be treated as operands(values), even if they looklike optionsdue to starting with -, as Jacob C.notes.

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

回答by David Thomas

To rename files, you can use the renameutility:

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

brew install rename

brew install rename

For example, to change a search string in all filenames in current directory:

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

rename -nvs searchword replaceword *

Remove the 'n' parameter to apply the changes.

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

More info: man rename

更多信息: man rename

回答by l'L'l

You could use sed:

你可以使用 sed:

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

result:

结果:

prefix_567.png prefix_efg.png

*to do a dry-run first, replace mvat the end with echo

*首先进行试运行,最后替换mvecho

Explanation:

解释:

  • e: optional for only 1 sed command.
  • p: to print the input to sed, in this case it will be the original file name before any renaming
  • @: is a replacement of / character to make sed more readable. That is, instead of using sed s/search/replace/g, use s@search@replace@g
  • _.* : the underscore is an escape character to refer to the actual '.' character zero or more times (as opposed to ANY character in regex)
  • -n2: indicates that there are 2 outputs that need to be passed on to mv as parameters. for each input from ls, this sed command will generate 2 output, which will then supplied to mv.
  • e:仅适用于 1 个 sed 命令。
  • p:将输入打印到 sed,在这种情况下,它将是任何重命名之前的原始文件名
  • @: 是 / 字符的替代品,使 sed 更具可读性。也就是说,不要使用 sed s/search/replace/g,而是使用 s@search@replace@g
  • _.* :下划线是一个转义字符,用于引用实际的“.” 字符零次或多次(与正则表达式中的任何字符相反)
  • -n2:表示有 2 个输出需要作为参数传递给 mv。对于来自ls 的每个输入,此 sed 命令将生成 2 个输出,然后将其提供给 mv。

回答by JanB

I had a batch of files that looked like this: be90-01.png and needed to change the dash to underscore. I used this, which worked well:

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

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

回答by Nisim Joseph

you can install renamecommand by using brew. just do brew install renameand use it.

您可以rename使用brew. 只是做brew install rename和使用它。

回答by α?sнιη

Using mmv

使用 mmv

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

回答by Joolah

try this

尝试这个

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

Here is another way:

这是另一种方式:

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