文件重命名循环无法正常工作

文件重命名循环无法正常工作

文件夹中有 32 个 *.dds 文件:

pic-0.dds, pic-1.dds, pic-2.dds,...,pic-31.dds

我想将它们重命名为:

015040.dds, 015041.dds, 015042.dds,...,0150471.dds.

我正在尝试使用以下脚本:

#!/bin/bash
j=39;
for i in *.dds;
do let j+=1;
mv $i 0150$j.dds;
done

我发现它pic-0.dds被重命名为015040.dds,但随后它出错了,即pic-1.dds没有重命名为015041.dds等等。

我想要一个用于其他重命名的通用脚本,例如:

pic-40.dds, pic-41.dds, pic-42.dds,...,pic-53.dds

到:

0191.dds, 0192.dds, 0193.dds,...,0204.dds

答案1

问题是pic-*.dds按字符顺序对文件进行排序,而不是按破折号后的数字排序。

0解决此问题的一种可能方法是在名为 的文件的破折号后面插入pic-{0..9}.dds.然后按字母顺序列出文件将与按编号排序相同,一切都会正常。

您可以通过使用与您已经使用过的循环类似的循环来做到这一点:

for f in pic-?.dds ; do
    mv "$f" pic-0"${f#pic-}"
done

${f#pic-}是一个参数替换,该符号告诉 shell从变量 $f 值的开头#删除字符串。pic-

答案2

不需要 shellfor循环,您可以使用 perlrename来实现。

perlrename实用程序也称为file-renameperl-rename、 或prename,具体取决于您的发行版。不要将其与具有完全不同且不兼容的功能和命令行选项的rename实用程序混淆。 util-linuxPerlrename允许您使用任意复杂的 Perl 代码来重命名文件,但最常用于对文件名执行简单的sed类似s/search/replace/操作。

例如:

$ rename -n 's/pic-(\d+)\.dds$/sprintf("015%03i.dds",$1+40)/e' *.dds
rename(pic-0.dds, 015040.dds)
rename(pic-10.dds, 015050.dds)
rename(pic-11.dds, 015051.dds)
rename(pic-12.dds, 015052.dds)
rename(pic-13.dds, 015053.dds)
rename(pic-14.dds, 015054.dds)
rename(pic-15.dds, 015055.dds)
rename(pic-16.dds, 015056.dds)
rename(pic-17.dds, 015057.dds)
rename(pic-18.dds, 015058.dds)
rename(pic-19.dds, 015059.dds)
rename(pic-1.dds, 015041.dds)
rename(pic-20.dds, 015060.dds)
rename(pic-21.dds, 015061.dds)
rename(pic-22.dds, 015062.dds)
rename(pic-23.dds, 015063.dds)
rename(pic-24.dds, 015064.dds)
rename(pic-25.dds, 015065.dds)
rename(pic-26.dds, 015066.dds)
rename(pic-27.dds, 015067.dds)
rename(pic-28.dds, 015068.dds)
rename(pic-29.dds, 015069.dds)
rename(pic-2.dds, 015042.dds)
rename(pic-30.dds, 015070.dds)
rename(pic-31.dds, 015071.dds)
rename(pic-3.dds, 015043.dds)
rename(pic-4.dds, 015044.dds)
rename(pic-5.dds, 015045.dds)
rename(pic-6.dds, 015046.dds)
rename(pic-7.dds, 015047.dds)
rename(pic-8.dds, 015048.dds)
rename(pic-9.dds, 015049.dds)

这会捕获文件名中的数字pic-*.dds并将它们添加到 40 以构建最终的文件名。替换操作s/search/replace/使用 perl 的/e修饰符来使其将右侧替换作为 perl 代码执行。该sprintf函数用于确保计算格式为 3 位宽的零填充字符串 ( %03i)。

  • 无论它看到文件名的顺序如何,这都会起作用 - 它不使用递增计数器,它从pic-(\d+).dds$文件名中提取现有数字并添加 40。
  • 与该模式不匹配的文件名不会被重命名
  • perl rename 不会覆盖现有文件名(除非您使用该-f选项强制它)。

请注意,-n上例中的选项使其成为空运行,因此它只会展示在不实际重命名任何文件的情况下它会做什么。当您确认它符合您的要求后,请删除-n或将其替换为详细输出。-v

相关内容