如何以特定格式重命名文件夹中的多个文件?
How to rename multiple files in a folder with a specific format?
我在一个文件夹中有很多文件,格式为“{galaxyID}-cutout-HSC-I-{#}-pdr2_wide.fits”,其中 {galaxyID} 和 {#} 是每个文件的不同编号文件。以下是一些示例:
2185-cutout-HSC-I-9330-pdr2_wide.fits
992-cutout-HSC-I-10106-pdr2_wide.fits
2186-cutout-HSC-I-9334-pdr2_wide.fits
我想更改此文件夹中所有文件的格式以匹配以下内容:
2185_HSC-I.fits
992_HSC-I.fits
2186_HSC-I.fits
即,我想从每个文件名中取出“cutout”、第二个数字和“pdr2_wide”。我更愿意在 Perl 或 Python 中执行此操作。对于我的 Perl 脚本,到目前为止我有以下内容:
rename [-n];
my @parts=split /-/;
my $this=$parts[0].$parts[1].$parts[2].$parts[3].$parts[4].$parts[5];
$_ = $parts[0]."_".$parts[2]."_".$parts[3];
*fits
这给了我错误信息
Not enough arguments for rename at ./rename.sh line 3, near "];" Execution of ./rename.sh aborted due to compilation errors.
我加入了 [-n]
是因为我想在实际执行之前确保所做的更改是我想要的;无论哪种方式,为了安全起见,它都在一个重复的目录中。
根据你的描述 {galaxyID}-cutout-HSC-I-{#}-pdr2_wide.fits
,我认为 cutout-HSC-I
是固定的。
这是一个可以重命名的脚本。它需要 stdin
上的文件列表。但是,您可以适应 readdir
:
的输出
#!/usr/bin/perl
master(@ARGV);
exit(0);
sub master
{
my($oldname);
while ($oldname = <STDIN>) {
chomp($oldname);
# find the file extension/suffix
my($ix) = rindex($oldname,".");
next if ($ix < 0);
# get the suffix
my($suf) = substr($oldname,$ix);
# only take filenames of the expected format
next unless ($oldname =~ /^(\d+)-cutout-(HSC-I)/);
# get the new name
my($newname) = . "_" . . $suf;
printf("OLDNAME: %s NEWNAME: %s\n",$oldname,$newname);
# rename the file
# change to "if (1)" to actually do it
if (0) {
rename($oldname,$newname) or
die("unable to rename '$oldname' to '$newname' -- $!\n");
}
}
}
对于示例输入文件,程序输出如下:
OLDNAME: 2185-cutout-HSC-I-9330-pdr2_wide.fits NEWNAME: 2185_HSC-I.fits
OLDNAME: 992-cutout-HSC-I-10106-pdr2_wide.fits NEWNAME: 992_HSC-I.fits
OLDNAME: 2186-cutout-HSC-I-9334-pdr2_wide.fits NEWNAME: 2186_HSC-I.fits
以上是我通常做事的方式,但这里只有一个正则表达式。 [出于安全考虑],它接受的内容相当严格,但您可以根据需要进行调整:
#!/usr/bin/perl
master(@ARGV);
exit(0);
sub master
{
my($oldname);
while ($oldname = <STDIN>) {
chomp($oldname);
# only take filenames of the expected format
next unless ($oldname =~ /^(\d+)-cutout-(HSC-I)-\d+-pdr2_wide([.].+)$/);
# get the new name
my($newname) = . "_" . . ;
printf("OLDNAME: %s NEWNAME: %s\n",$oldname,$newname);
# rename the file
# change to "if (1)" to actually do it
if (0) {
rename($oldname,$newname) or
die("unable to rename '$oldname' to '$newname' -- $!\n");
}
}
}
看起来您正在使用 Ubuntu 上的 rename
(它不是我的 ArchLinux 盒子上的那个),但还有其他的。但是,你的表现很奇怪。 -n
周围的括号不应该存在,;
结束命令。
语法,如果你使用的是我认为的,是这样的:
% rename -n -e PERL_EXPR file1 file2 ...
Perl 表达式是 -e
开关的参数,可以是一个简单的替换。请注意,此表达式是您提供给 -e
的字符串,因此可能需要引用:
% rename -n -e 's/-\d+-pdr2_wide//' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-cutout-HSC-I.fits)
而且,我不会一步完成,而是分两步完成:
% rename -n -e 's/-cutout-/-/; s/-\d+-pdr2_wide//' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-HSC-I.fits)
还有其他可能有意义的模式。你可以保留零件,而不是拿走零件:
% rename -n -e 's/\A(\d+).*(HSC-I).*/-.fits/' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-HSC-I.fits)
我倾向于使用命名捕获,以便下一个可怜的懒汉知道你在做什么:
% rename -n -e 's/\A(?<galaxy>\d+).*(HSC-I).*/$+{galaxy}-.fits/' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-HSC-I.fits)
我在一个文件夹中有很多文件,格式为“{galaxyID}-cutout-HSC-I-{#}-pdr2_wide.fits”,其中 {galaxyID} 和 {#} 是每个文件的不同编号文件。以下是一些示例:
2185-cutout-HSC-I-9330-pdr2_wide.fits
992-cutout-HSC-I-10106-pdr2_wide.fits
2186-cutout-HSC-I-9334-pdr2_wide.fits
我想更改此文件夹中所有文件的格式以匹配以下内容:
2185_HSC-I.fits
992_HSC-I.fits
2186_HSC-I.fits
即,我想从每个文件名中取出“cutout”、第二个数字和“pdr2_wide”。我更愿意在 Perl 或 Python 中执行此操作。对于我的 Perl 脚本,到目前为止我有以下内容:
rename [-n];
my @parts=split /-/;
my $this=$parts[0].$parts[1].$parts[2].$parts[3].$parts[4].$parts[5];
$_ = $parts[0]."_".$parts[2]."_".$parts[3];
*fits
这给了我错误信息
Not enough arguments for rename at ./rename.sh line 3, near "];" Execution of ./rename.sh aborted due to compilation errors.
我加入了 [-n]
是因为我想在实际执行之前确保所做的更改是我想要的;无论哪种方式,为了安全起见,它都在一个重复的目录中。
根据你的描述 {galaxyID}-cutout-HSC-I-{#}-pdr2_wide.fits
,我认为 cutout-HSC-I
是固定的。
这是一个可以重命名的脚本。它需要 stdin
上的文件列表。但是,您可以适应 readdir
:
#!/usr/bin/perl
master(@ARGV);
exit(0);
sub master
{
my($oldname);
while ($oldname = <STDIN>) {
chomp($oldname);
# find the file extension/suffix
my($ix) = rindex($oldname,".");
next if ($ix < 0);
# get the suffix
my($suf) = substr($oldname,$ix);
# only take filenames of the expected format
next unless ($oldname =~ /^(\d+)-cutout-(HSC-I)/);
# get the new name
my($newname) = . "_" . . $suf;
printf("OLDNAME: %s NEWNAME: %s\n",$oldname,$newname);
# rename the file
# change to "if (1)" to actually do it
if (0) {
rename($oldname,$newname) or
die("unable to rename '$oldname' to '$newname' -- $!\n");
}
}
}
对于示例输入文件,程序输出如下:
OLDNAME: 2185-cutout-HSC-I-9330-pdr2_wide.fits NEWNAME: 2185_HSC-I.fits
OLDNAME: 992-cutout-HSC-I-10106-pdr2_wide.fits NEWNAME: 992_HSC-I.fits
OLDNAME: 2186-cutout-HSC-I-9334-pdr2_wide.fits NEWNAME: 2186_HSC-I.fits
以上是我通常做事的方式,但这里只有一个正则表达式。 [出于安全考虑],它接受的内容相当严格,但您可以根据需要进行调整:
#!/usr/bin/perl
master(@ARGV);
exit(0);
sub master
{
my($oldname);
while ($oldname = <STDIN>) {
chomp($oldname);
# only take filenames of the expected format
next unless ($oldname =~ /^(\d+)-cutout-(HSC-I)-\d+-pdr2_wide([.].+)$/);
# get the new name
my($newname) = . "_" . . ;
printf("OLDNAME: %s NEWNAME: %s\n",$oldname,$newname);
# rename the file
# change to "if (1)" to actually do it
if (0) {
rename($oldname,$newname) or
die("unable to rename '$oldname' to '$newname' -- $!\n");
}
}
}
看起来您正在使用 Ubuntu 上的 rename
(它不是我的 ArchLinux 盒子上的那个),但还有其他的。但是,你的表现很奇怪。 -n
周围的括号不应该存在,;
结束命令。
语法,如果你使用的是我认为的,是这样的:
% rename -n -e PERL_EXPR file1 file2 ...
Perl 表达式是 -e
开关的参数,可以是一个简单的替换。请注意,此表达式是您提供给 -e
的字符串,因此可能需要引用:
% rename -n -e 's/-\d+-pdr2_wide//' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-cutout-HSC-I.fits)
而且,我不会一步完成,而是分两步完成:
% rename -n -e 's/-cutout-/-/; s/-\d+-pdr2_wide//' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-HSC-I.fits)
还有其他可能有意义的模式。你可以保留零件,而不是拿走零件:
% rename -n -e 's/\A(\d+).*(HSC-I).*/-.fits/' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-HSC-I.fits)
我倾向于使用命名捕获,以便下一个可怜的懒汉知道你在做什么:
% rename -n -e 's/\A(?<galaxy>\d+).*(HSC-I).*/$+{galaxy}-.fits/' *.fits
rename(2185-cutout-HSC-I-9330-pdr2_wide.fits, 2185-HSC-I.fits)