根据从子文件夹中提取的数字更改子文件夹中的文件名

根据从子文件夹中提取的数字更改子文件夹中的文件名

我有一个文件夹,里面有几个子文件夹,其中有一个在所有子文件夹中都同名的文件。例如:

  • abc/def_0/ghi.jpg
  • abc/def_5/ghi.jpg
  • abc/def_10/ghi.jpg
  • ...
  • abc/pqr_0/ghi.jpg
  • abc/pqr_5/ghi.jpg
  • abc/pqr_10/ghi.jpg

我想将ghi.jpg所有子文件夹中的此特定文件()重命名为:

  • abc/def_0/def_xyz_0.jpg
  • abc/def_5/def_xyz_5.jpg
  • abc/def_10/def_xyz_10.jpg
  • ...
  • abc/pqr_0/pqr_xyz_0.jpg
  • abc/pqr_5/pqr_xyz_5.jpg
  • abc/pqr_10/pqr_xyz_10.jpg

我将非常感激任何帮助,因为我无法找到解决方案。谢谢!

答案1

您可以使用 Perl 重命名命令file-rename为此。如果您不熟悉此工具,我建议您运行file-rename --version以查看是否有它 - 任何非错误输出都表示您有。一些 Ubuntu 版本默认不附带它,因此您可能没有它,在这种情况下,您可以通过安装包来获取它rename。(如果您没有它,“未找到命令”错误甚至可能会告诉您这一点。)

cdabc包含要重命名文件的子目录的目录中并运行此命令。然后,如果它显示的重命名操作确实是您想要的,则再次运行它而无需-n执行实际的重命名。

file-rename -n 's|^(.+)_(\d+)/ghi\.jpg$|$1_$2/$1_xyz_$2.jpg|' */ghi.jpg

这将使用 shell glob 生成要重命名的文件列表,并将其作为参数传递给要file-rename重命名的文件。它假定您想要:

  • 要重命名ghi.jpg位于目录的子目录中_的文件(以 结尾,后跟数字)abc
  • 每个文件的新名称为其包含的目录没有尾随下划线和数字,后跟xyz,后跟其包含目录名称的尾随下划线和数字。

其工作方式是,对文件进行操作,这些文件的路径作为参数传递给匹配s|pattern|substitution|file-renamepattern(解释为正则表达式Perl 方言)。它执行的操作是使用指定的substitution. 名称不包含匹配项的文件pattern不会被重命名。分隔符的选择并没有什么特别之处|;我只是不想使用通常的分隔符,/因为它出现在路径中。

在模式中^(.+)_(\d+)/ghi\.jpg$

  • ^匹配路径的开头和$结尾。这只允许匹配传入的每个路径的整体,而不是其中的任何部分。

    (为了解决一个可能引起混淆的问题:传递的路径仍然是相对路径类似def_0/ghi.jpg,而不是类似 的绝对路径/home/you/abc/def_0/ghi.jpg。当人们谈论“完整路径”时,他们通常指的是绝对路径。我说的“整个路径”只是指传入的每个完整参数,而不是其中较小的子字符串。)

  • (.+)比赛和捕获( ))一个或多个序列(+) 任何字符 (.)。这将进入第一个捕获组。

  • _匹配其自身,即文字下划线字符。

  • (\d+)比赛和捕获( ))一个或多个序列(+) 位数字 (\d)。这将进入第二个捕获组。

  • /匹配其自身,即文字斜杠字符。(它不充当分隔符,因为我们改用了|分隔符。)

  • ghi与文字文本匹配ghi

  • \.仅匹配一个.字符。\ 逃脱;否则.. 意味着“任何字符。”

  • jpg与文字文本匹配jpg

替代$1_$2/$1_xyz_$2.jpg意味着:

  • 放置在第一个捕获组 ( ) 中的文本。这是与模式$1匹配的文本。.+
  • 下划线,_
  • 放置在第二个捕获组 ( ) 中的文本。这是与模式$2匹配的文本。\d+
  • 一道斜线,/
  • 再次是第一个捕获组($1)。
  • 文本_xyz_
  • 再次是第二个捕获组($2)。
  • 点,.。与模式不同,在替换中 a.不会被特殊处理,因此不需要(也不应该)用 进行转义\
  • 文本jpg

有关使用的一般文档file-rename,请参阅的输出file-rename --helpman file-rename, 和这篇博文。(我使用file-rename而不是 命令rename,因为在某些系统上rename是另一个实用程序。在大多数系统中它们是相同的。)

相关内容