使用基于 Perl 的rename
命令
如果你有一个基于 Perl 的rename
命令,那就很简单了:
rename 's/(\d{4})/0$1/' *-????.png
我顺便指出,如果您确实有大约 10,000 个剪辑要重命名,您可能需要使用xargs
或find
避免“参数列表太长”的问题。
find . -name 'clip-????.png' -exec rename 's/(\{4})/0$1/' {} +
或者:
find . -name 'clip-????.png' -print | xargs rename 's/(\d{4})/0$1/'
由于您的姓名不包含空格,因此两者都可以。如果需要担心空格,请使用find
-only 变体,假设您find
支持 POSIX 2008+
表示法到find
. 这可以应用于任何其他答案,但要小心。
我注意到这个 Perl 脚本避免了必须执行mv
10,000 次,因此它可能超过mv
为每个文件重命名执行的任何 shell 脚本。对于一次性练习,这可能无关紧要,但当您获得超过 100,000 个剪辑时,它就会成为一个更大的问题。
此外,下面的脚本具有读取文件名的选项,每行一个,但它会将整个文件名吞入内存,效率不高(但存在于脚本的原始版本中并已保留,即使虽然我几乎没有使用过这个选项)。假设一台正常的现代机器(比如 1 GiB 的内存,但更少的内存就足够了),这不会成为一个问题,只有 10,000 个名称,每个名称长度为 12 个字符。所以你也可以使用:
find . -name 'clip-????.png' -print | rename 's/(\d{4})/0$1/'
基于 Perl 的rename
脚本
如果您没有基于 Perl 的rename
命令,我会使用这个。它最初来自骆驼书的第一版,但多年来已经进行了一些修改:
#!/usr/bin/env perl
#
# @(#)$Id: rename.pl,v 1.8 2011/06/03 22:30:22 jleffler Exp $
#
# Rename files using a Perl substitute or transliterate command
use strict;
use warnings;
use Getopt::Std;
my(%opts);
my($usage) = "Usage: $0 [-fnxV] perlexpr [filenames]\n";
my($force) = 0;
my($noexc) = 0;
my($trace) = 0;
die $usage unless getopts('fnxV', \%opts);
if ($opts{V})
{
printf "%s\n", q'RENAME Version $Revision: 1.8 $ ($Date: 2011/06/03 22:30:22 $)';
exit 0;
}
$force = 1 if ($opts{f});
$noexc = 1 if ($opts{n});
$trace = 1 if ($opts{x});
my($op) = shift;
die $usage unless defined $op;
if (!@ARGV) {
@ARGV = <STDIN>;
chop(@ARGV);
}
for (@ARGV)
{
if (-e $_ || -l $_)
{
my($was) = $_;
eval $op;
die $@ if $@;
next if ($was eq $_);
if ($force == 0 && -f $_)
{
print STDERR "rename failed: $was - $_ exists\n";
}
else
{
print "+ $was --> $_\n" if $trace;
print STDERR "rename failed: $was - $!\n"
unless ($noexc || rename($was, $_));
}
}
else
{
print STDERR "$_ - $!\n";
}
}