我希望通过在文件前添加文件夹名称来递归重命名文件。例如:c:\test\foo\a.txt
将成为c:\test\foo\foo-a.txt
。
答案 0 :(得分:4)
以下Perl脚本可能适合您:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Basename;
use File::Find;
use File::Spec;
sub rename {
my ($dir_name) = ( File::Spec->splitdir($File::Find::dir) )[-1];
my $file_name = basename $_;
if ( -f $_ ) {
$file_name = "$dir_name-$file_name";
rename $_, File::Spec->catdir( $File::Find::dir, $file_name );
}
}
find { 'wanted' => \&rename, 'no_chdir' => 1 }, 'C:/test/foo';
答案 1 :(得分:4)
use File::Find::Rule qw( );
use Path::Class qw( dir file );
my $base = dir('.')->absolute;
for my $qfn (File::Find::Rule->file->in($base)) {
my $file = file($qfn);
my $dir = $file->dir;
my $src = $file;
my $dst = $dir->file($dir->basename . '-' . $file->basename);
if (-e $dst) {
warn("Can't rename $src to $dst: Already exists\n");
}
elsif (!rename($src, $dst)) {
warn("Can't rename $src to $dst: $!\n");
}
}
答案 2 :(得分:1)
use strict;
use warnings;
use File::Spec;
use File::Copy qw(move);
use File::Glob qw(:glob);
my $folder_path = qw( c:\test\foo\ );
my @file_paths = bsd_glob( $folder_path . '*' );
foreach my $old_path (@file_paths) {
if ( -f $old_path ) {
my ( $volume, $directories, $file ) = File::Spec->splitpath($old_path);
my @dirs = File::Spec->splitdir($directories);
my $prepend;
while ( !( $prepend = pop @dirs ) ) { } # see notes below
my $new_fname = $prepend . '-' . $file;
my $new_path = File::Spec->catpath( $volume, $directories, $new_fname );
move( $old_path, $new_path );
}
}
我使用while来弹出文件名前的最后一个目录名,因为splitdir
在Windows上有一个警告。看起来您正在处理Windows文件。
答案 3 :(得分:1)
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use File::Find;
use File::Spec;
($#ARGV == 0) or die "Usage: $0 [directory]\n";
my $input_file_dir = $ARGV[0];
sub process_file
{
my $dir_name = (File::Spec -> splitdir ($File::Find::dir)) [-1];
my $file_name = basename $_;
my $extension = ($file_name =~ m/([^.]+)$/)[0];
if ( -f $_ )
{
print "$dir_name.$extension\n";
rename $_, "$dir_name.$extension";
}
}
finddepth { 'wanted' => \&process_file, 'no_chdir' => 0 }, $input_file_dir;