通过使用shell脚本替换文件名中的特定模式来重命名多个文件

sta*_*ion 119 shell

编写一个简单的脚本,自动重命名一些文件.作为一个例子,我们希望将文件*001.jpg重命名为用户定义的字符串+ 001.jpg(例如:MyVacation20110725_001.jpg)此脚本的用法是让数码相机照片具有合理的文件名.

我需要为此编写一个shell脚本.有人可以建议如何开始吗?

Sus*_*Pal 195

一个帮助您开始工作的例子.

for f in *.jpg; do mv "$f" "$(echo "$f" | sed s/IMG/VACATION/)"; done
Run Code Online (Sandbox Code Playgroud)

在此示例中,我假设您的所有图像文件都以"IMG"开头,并且您希望将"IMG"替换为"VACATION".

shell会自动评估*.jpg所有匹配的文件.

mv(文件的新名称)的第二个参数sed是将"IMG"替换为"VACATION" 的命令的输出.

如果您的文件名包含多个连续空格,请特别注意"$f"符号.您需要双引号来保留这些空格.

  • 使用bash,您还可以从字符串重定向:`sed's/foo/bar /'<<<"$ f"` (5认同)
  • 很好的例子Susam -这种用法在MingW中也对我有用,可以将名为**-1.0-SNAPSHOT.war的文件更改为`* .war`,如下所示:做mv $ {i} \`echo $ {i} | sed's / -1.0-SNAPSHOT \ .war / \。war /'\`; 完成` (2认同)
  • @MikeStewart 您链接到的 GNU 文档提供了许多非 POSIX 功能。有关参数扩展的 POSIX 规范,请参阅 [POSIX.1-2008:§ 2.6.2:参数扩展](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02)。您链接到的其他答案中的“${file//IMG/myVacation}”替换不符合 POSIX。它不适用于“破折号”。在 Debian 上,默认的 `sh` 是 `dash`。当 `dash` 遇到 `${file//IMG/myVacation}` 时,它会失败并出现 `Bad replacement` 错误,因为此语法不符合 POSIX。 (2认同)

ted*_*ted 157

您可以使用重命名实用程序按模式重命名多个文件.例如,以下命令将字符串MyVacation2011_添加到具有jpg扩展名的所有文件.

rename 's/^/MyVacation2011_/g' *.jpg
Run Code Online (Sandbox Code Playgroud)

要么

rename <pattern> <replacement> <file-list>
Run Code Online (Sandbox Code Playgroud)

  • @ ixe013这个重命名是perl版本,不是内置实用程序.按照http://stackoverflow.com/questions/22577767/get-the-perl-rename-utility-instead-of-the-built-in-rename上的指南进行安装. (6认同)
  • 这应该是公认的答案.解决方案比其他答案简单得多. (4认同)
  • 可以通过使用`find`:`find来解决“参数列表太长”的问题。-name * .jpg -exec重命名&lt;pattern&gt; &lt;replacement&gt; {} \;`这将为每个文件调用一次重命名。 (2认同)

小智 28

for file in *.jpg ; do mv $file ${file//IMG/myVacation} ; done
Run Code Online (Sandbox Code Playgroud)

再次假设您的所有图像文件都有字符串"IMG",并且您想要将"IMG"替换为"myVacation".

使用bash,您可以使用参数扩展直接转换字符串.

示例:如果文件是IMG_327.jpg,mv则将执行该命令mv IMG_327.jpg myVacation_327.jpg.这将针对目录匹配中找到的每个文件完成*.jpg.

IMG_001.jpg - > myVacation_001.jpg
IMG_002.jpg - > myVacation_002.jpg
IMG_1023.jpg - > myVacation_1023.jpg etcetera
......

  • @MikeStewart 您链接到的 GNU 文档提供了许多非 POSIX 功能。有关参数扩展的 POSIX 规范,请参阅 [POSIX.1-2008:§ 2.6.2:参数扩展](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02)。此答案中的“${file//IMG/myVacation}”替换不符合 POSIX。它不适用于“破折号”。在 Debian 上,默认的 `sh` 是 `dash`。当 `dash` 遇到 `${file//IMG/myVacation}` 时,它会失败并出现 `Bad replacement` 错误,因为此替换语法不符合 POSIX。 (2认同)

Suj*_*ale 21

这个例子,我假设您的所有图像文件都以"IMG"开头,并且您希望将"IMG"替换为"VACATION"

解决方案:首先确定所有jpg文件,然后替换关键字

find . -name '*jpg' -exec bash -c 'echo mv $0 ${0/IMG/VACATION}' {} \; 
Run Code Online (Sandbox Code Playgroud)

  • 这里只是一个注释...很明显但值得一提:`'echo mv $0 ${0/IMG/VACATION}'` 部分是将针对找到的每个文件运行的实际命令。所以,如果你把 `echo` 留在那里,它只会回应它会做什么。删除 `echo` 命令以实际移动文件,例如。`找到。-name '*jpg' -exec bash -c 'mv $0 ${0/IMG/VACATION}' {} \; ` (6认同)
  • 最佳答案,因为它允许遍历目录树,使用内置的bash实用程序并且易于配置。此外,该示例还进行了非破坏性测试,以确保更改正确无误。 (2认同)
  • 感谢包含“echo”,以便用户知道它是否有效 (2认同)

Joh*_*ick 13

find . -type f | 
sed -n "s/\(.*\)factory\.py$/& \1service\.py/p" | 
xargs -p -n 2 mv
Run Code Online (Sandbox Code Playgroud)

例如,将重命名 cwd 中名称以“factory.py”结尾的所有文件,以替换为以“service.py”结尾的名称

解释:

  1. sedcmd 中,该-n标志将抑制在应用 s/// 命令后将输入回显到输出的正常行为,并且p如果进行替换,s/// 上的选项将强制写入输出。由于子只会在匹配时进行,因此 sed 只会输出以“factory.py”结尾的文件

  2. 在 s/// 替换字符串中,我们使用“ & ”将整个匹配字符串插入到替换字符串中,后跟一个空格字符。因此,我们的 RE 匹配整个文件名至关重要。在空格字符之后,我们使用“\1service.py”来插入我们在“factory.py”之前吞下的字符串,然后用“service.py”替换它。因此,对于更复杂的转换,您必须将参数更改为 s/// (re 仍然匹配整个文件名)

输出示例:

foo_factory.py foo_service.py
bar_factory.py bar_service.py
Run Code Online (Sandbox Code Playgroud)
  1. 我们使用xargswith-n 2一次使用 sed 2 个分隔字符串的输出,将它们传递给 mv (我还将 -p 选项放在那里,这样你在运行它时可以感到安全)。瞧。

注意:如果您面临更复杂的文件和文件夹场景,这篇文章将更find详细地解释(以及一些替代方案)