2010-03-31 113 views
6

我需要遞歸重命名每個文件和目錄。我將空格轉換爲下劃線,並將所有文件/目錄名稱改爲小寫。如何讓以下腳本在一次運行中重命名所有文件?目前,在轉換所有文件/目錄之前,腳本需要運行多次。代碼如下:Perl:遞歸重命名所有文件和目錄

#!/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); 
+2

如果「某個文件名」和「某個文件名」都存在於同一個目錄中,會發生什麼?對於非空目錄「Some Dir」和「some_dir」與同一個父級? – 2010-03-31 23:35:23

+0

你知道Perl帶有重命名(3)腳本嗎? – 2010-03-31 23:50:11

+0

@Pasi:這是「prename」。由於某種原因,Debian決定一如既往地將事情弄糟,並將其重命名爲「重命名」,從userlinux中取代原來的重命名。 – Juliano 2010-04-01 17:45:45

回答

4

要麼你需要的選項來指定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; 
1

,如果你是開放給其他的方法,這裏有一個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) 
+0

我用上面的腳本,我發現它工作得很好。感謝分享:) – Horizon 2013-07-12 20:04:31

0

您可以通過目錄遍歷之前重命名文件。

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")
      rename "Abc Def" => "abc_def"
find嘗試進入"Abc Def",它不存在了
       因此,下面的所有內容都沒有得到處理

相關問題