文件夹中有 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-rename
、perl-rename
、 或prename
,具体取决于您的发行版。不要将其与具有完全不同且不兼容的功能和命令行选项的rename
实用程序混淆。 util-linux
Perlrename
允许您使用任意复杂的 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