【问题标题】:Script to rename files in a Windows subdirectory用于重命名 Windows 子目录中文件的脚本
【发布时间】:2011-01-12 04:24:33
【问题描述】:

有人可以建议一个脚本来重命名 Windows 子目录中的一堆文件,文件名有空格,而文件名有下划线。例如,如果文件名是

abc xyz.pdf

应该是

abc_xyz.pdf

【问题讨论】:

  • 是否需要递归到子目录的子目录中?
  • 是的,递归到目录中
  • 如果任何子目录名称中有空格怎么办?保持原样?还是改名?如果重命名,我认为不应该重命名父目录空间?例如。如果您从C:\my docs\pdfs 开始,并且有一个文件C:\my docs\pdfs\sci fi\star wars1.pdf,它应该以C:\my docs\pdfs\sci fi\star_wars1.pdfC:\my docs\pdfs\sci_fi\star_wars1.pdf 还是C:\my_docs\pdfs\sci_fi\star_wars1.pdf 结尾?我假设 #1。
  • 我只想更改文件名,而不是目录

标签: perl vbscript


【解决方案1】:

Perl:使用File::Find 对文件进行递归查找和操作。

请注意,您需要注意:不要重命名带有下划线的 DIRECTORIES,例如 File::Basename

use File::Find;
use File::Basename;
use File::Spec;
use strict;

find ({ 'wanted' => \&renamefile }, 'X:\my\sub\dir');

sub renamefile {
    my $file = $_;
    return unless (-f $file);   # Don't rename directories!
    my $dirname = dirname($file); # file's directory, so we rename only the file itself.
    my $file_name = basename($file); # File name fore renaming.
    my $new_file_name = $file_name;
    $new_file_name =~ s/ /_/g; # replace all spaces with underscores
    rename($file, File::Spec->catfile($dirname, $new_file_name))
        or die $!; # Error handling - what if we couldn't rename?
}

【讨论】:

  • 如对问题的评论中所述,如果 (1) 起始目录中的子目录有空格并且 (2) 起始目录有空格会发生什么情况尚不清楚。我假设上面代码中的答案是“什么都没有”;如果你想重命名子目录而不是起始目录,它会变得有点复杂。
  • 像这样。我也需要。
【解决方案2】:

以下批处理文件未经测试,但应该可以工作。

@echo off
for %%i in (*) do call :rename "%%~ni"
goto :EOF

:rename
set filename=%1
set newname=%filename: =_%
rename "filename" "newname"

【讨论】:

    【解决方案3】:

    这是 VBSCript 脚本。它将重命名文件夹 C:\Test

    中的文件 暗淡 fso, f, f1, fc, s 设置 fso = CreateObject("Scripting.FileSystemObject") 设置 f = fso.GetFolder("C:\Test") 设置 fc = f.Files 对于 fc 中的每个 f1 f1.move f1.ParentFolder & "\" & replace(f1.Name, " ", "_") 下一个

    【讨论】:

    • 我认为您的f1.move 行中可能存在语法错误。
    • 没有语法错误。它虽然不通过目录运行。 VBScript 没有 renamefile 方法。移动就是它的方法。
    【解决方案4】:

    我还在学习 PERL,所以尝试了一下...

    opendir (curDir, ".");
    
    @filesWithSpaces = grep(/.*\s.*\..*/, readdir (curDir));
    
    foreach $oneFile (@filesWithSpaces){
      $newName = $oneFile;
      $newName =~ s/\ /_/g;
      print "RENAMING: $oneFile -> $newName \n";
      rename($oneFile, $newName);
    

    }

    在我的初始测试中看起来不错。但它不是递归的。

    【讨论】:

    • 这有几个错误,例如重命名目录名称中的空格。
    【解决方案5】:

    这是一个有效的 VBScript。但是它不会递归到指定目录的子目录中。

    Dim fso
    Dim folder
    Dim stringToFind
    Dim replacement
    
    ' Check arguments
    If Wscript.Arguments.Count <> 3 Then
        ' Usage
        Wscript.echo "Usage: rename.vbs folder string_to_find replacement"
        WScript.Quit
    End If
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Set folder = fso.GetFolder(WScript.Arguments(0))
    
    If Err.Number <> 0 Then
        WScript.Echo "Folder " & WScript.Arguments(0) & " does not exist."
        WScript.Quit
    End If
    
    stringToFind = WScript.Arguments(1)
    replacement = WScript.Arguments(2)
    
    For Each file in folder.Files
        fso.MoveFile file.ParentFolder & "\" & file.Name, file.ParentFolder & "\" & Replace(file.Name, stringToFind, replacement)
    Next
    
    Set folder = Nothing
    Set fso = Nothing
    

    【讨论】: