我需要recursion重命名每个文件和目录。 我将空格转换为下划线,并使所有文件/目录名称为小写。 如何使下列脚本在一次运行中重命名所有文件? 目前,在转换所有文件/目录之前,脚本需要运行多次。 代码如下:
#!/usr/bin/perl use File::Find; $input_file_dir = $ARGV[0]; sub process_file { $clean_name=lc($_); $clean_name=~s/\s/_/g; rename($_,$clean_name); print "file/dir name: $clean_name\n"; } find(\&process_file, $input_file_dir);
您需要在您传递的选项中指定bydepth => 1
来查找或调用finddepth
。 来自perldoc File :: Find :
bydepth
仅在报告所有条目后报告目录的名称。 入口点
finddepth()
是在find()
的第一个参数中指定{ bydepth => 1 }
的快捷方式。
但是, 您仍然需要决定如何处理命名冲突,因为如果目标存在,重命名将会破坏目标 。
#!/usr/bin/perl use strict; use warnings; use File::Find; finddepth(\&process_file, $_) for @ARGV;
如果你打开其他方法,这是一个Python解决方案
import os for R,DIR,FILES in os.walk("/mypath",topdown=False): for file in FILES: newfile=file.lower().replace(" ","_") new_file_name=os.path.join(R,newfile) os.rename( os.path.join(R,file) , new_file_name) for dir in DIR: newdir=dir.lower().replace(" ","_") new_dir_name=os.path.join(R,newdir) os.rename( os.path.join(R,dir) , new_dir_name)
在遍历目录之前,您可以重命名文件。
find({ preprocess => sub { for (@_) { my $oldname = $_; $_ = lc; s/\s/_/g; rename $oldname => $_; } return @_; }, wanted => sub { print "$File::Find::name was already renamed\n"; }, }, @dirs );
或者你可以延迟重命名,直到遍历发生。
finddepth(sub { print "in $File::Find::dir, renaming $_\n"; my $newname = lc; $newname =~ s/\s/_/g; rename $_ => $newname; }, @dirs );
你遇到的问题是因为
find
查找目录"Abc Def"
find
wanted("Abc Def")
电话wanted("Abc Def")
rename "Abc Def" => "abc_def"
find
尝试输入"Abc Def"
,这已经不存在了
所以下面的一切都没有得到处理