代码之家  ›  专栏  ›  技术社区  ›  Ghoul Fool

在批处理文件中使用循环重命名x为y

  •  -1
  • Ghoul Fool  · 技术社区  · 7 年前

    我在重命名文件时遇到字符串文本问题:

    我有许多包含子字符串x的文件,我想用它们代替文件名中任何部分可能出现的y。

    cheese.txt
    Sarah_cheese_Parker.txt
    cheese_Brookes.txt
    

    应成为:

    Louise.txt
    Sarah_Louise_Parker.txt
    Louise_Brookes.txt
    
    set x="cheese"
    set y="Louise"
    

    这就是我目前所拥有的

    for %%f in (x*.txt) do 
    (
        echo %%f
        call :processit "%%f"
    )
    goto finished
    
    :processit
    ren x%i%.txt y%i%.txt
    
    goto :finished
    
    :finished
    dir *.txt /b
    

    我不担心文件名中%的复杂化。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Mofi    2 年前

    批处理文件应存储在包含所有*的目录中。txt文件并双击执行。

    @echo off
    for /F "eol=| delims=" %%I in ('dir "*cheese*.txt" /A-D /B 2^>nul') do call :RenameFile "%%I"
    set "NewName="
    pause
    goto :EOF
    
    :RenameFile
    set "NewName=%~nx1"
    set "NewName=%NewName:cheese=Louise%"
    ren "%~1" "%NewName%"
    goto :EOF
    

    命令 目录 搜索

    • 仅针对文件,因为 /A-D (非属性目录)
    • 仅在当前目录中,因为不另外使用 /S
    • 对于*。包含以下内容的txt文件 cheese
    • 以裸格式输出,因为 /B 找到的具有文件扩展名但没有路径的文件的名称。

    这个 目录 命令行由执行 用于 在后台的单独命令进程中捕获此命令进程的输出(=命令 目录 )写入到句柄 标准装置 .

    输出的可能错误 目录 在目录中找不到任何与要处理的通配符模式匹配的文件时 斯特德尔 通过使用 2>nul 至设备 努尔 . 另请阅读有关Microsoft的文章 Using Command Redirection Operators 有关 2>努尔 . 重定向操作符 > 必须使用插入符号字符转义 ^ 在…上 用于 当Windows命令解释器在执行命令之前处理此命令行时,将命令行解释为文字字符 用于 执行嵌入的 dir 使用在后台启动的单独命令进程的命令行。

    命令 用于 处理从 目录 . 的默认行为 用于 toignore以开头的行 ; 被选项禁用 eol=| . 角色 | 不能在文件/文件夹名称中使用,因此不能位于文件/文件夹名称的开头。的默认行为 用于 选项禁用将水平制表符和空格上的每一行拆分为子字符串 delims= 指定空分隔符列表。所以 用于 确实为每个文件名指定了文件扩展名,但没有path to loop变量 I .

    在这里跑步很重要 用于 在捕获的文件名列表上,而不是 用于 它本身递归地搜索TXT文件,否则在文件重命名过程中可能会发生这种情况,即由于循环迭代过程中目录条目的更改,会跳过一些TXT文件。

    对于每个文件名,子例程 RenameFile 调用时,将完整文件名作为第一个参数传递给子例程,该参数用双引号括起来。双引号对于处理包含空格或其中一个字符的文件名也是必要的 &()[]{}^=;!'+,`~ 在文件名或文件路径中。

    使用一个子例程,而不是直接在 用于 循环,因为这需要使用延迟的环境变量扩展,如果处理文件的文件/文件夹名称碰巧包含一个或多个感叹号,则会导致问题。

    在子程序中 重命名文件 当前无路径文件的名称被指定给环境变量 NewName .

    接下来,对文件名应用字符串替换以替换不区分大小写的 全部的 发生的次数 干酪 通过 Louise .

    然后,根据命令的要求,通过指定要重命名的文件和具有无路径文件扩展名的新名称来执行文件重命名 .

    命令 回声 可以从左侧插入到 ren 首先运行批处理文件,检查文件重命名是否按预期进行。

    这个 目录 选项 /S 可在之后添加 /B类 还可以在当前目录的所有子目录中递归搜索*。包含的txt文件 干酪 在文件名中。在这种情况下 目录 将输出具有完整路径的所有文件名。但编写的批处理文件仍然可以正常工作。

    要了解使用的命令及其工作方式,请打开命令提示窗口,在那里执行以下命令,并仔细阅读为每个命令显示的所有帮助页。

    • call /?
    • dir /?
    • echo /?
    • for /?
    • goto /?
    • pause /?
    • ren /?
    • set /?

    另请参见 Where does GOTO :EOF return to?

        2
  •  1
  •   Aacini    7 年前

    此代码执行您想要的操作。请注意 *%x%*.txt 是“包含可能出现在文件名任何部分的子字符串x的文件”的通配符。

    @echo off
    setlocal EnableDelayedExpansion
    
    set "x=cheese"
    set "y=Louise"
    
    for %%f in (*%x%*.txt) do (
        echo %%f
        call :processit "%%f"
    )
    goto finished
    
    :processit
    set "name=%~1"
    ren "%~1" "!name:%x%=%y%!"
    exit /B
    
    :finished
    dir *.txt /b
    

    该解决方案的关键在于,只能用另一个子串替换一个子串 在变量中 ,因此有必要分配 %1 子例程参数 name 变量

    第二点是为了用另一个子串替换一个子串, 当两个字符串都存储在变量中时 ,您需要使用 标准 %expansion% 首先展开 x y 子字符串,然后是 延迟 !expansion! 在中执行替换 名称 变量这是通过以下方式实现的:

    ren "%~1" "!name:%x%=%y%!"
    

    最后一点是,在这种情况下,您实际上不需要子例程,因此最终代码可能更简单:

    @echo off
    setlocal EnableDelayedExpansion
    
    set "x=cheese"
    set "y=Louise"
    
    for %%f in (*%x%*.txt) do (
        echo %%f
        set "name=%%f"
        ren "%%f" "!name:%x%=%y%!"
    )
    dir *.txt /b