File 如何重命名部分文件夹名的文件?

File 如何重命名部分文件夹名的文件?,file,batch-file,File,Batch File,我有以下文件: H:\1\PICTURES\some\dir\sdir1[60]19\[0]-[30]15[60]-[65]-[999]abc.jpg H:\1\PICTURES\some\dir\sdir200\ssdir5[60]22\[0]20[30]15[60]--[65]22[999]abcd.jpg H:\1\PICTURES\some\dir\sdir20[60]218\[0]-[30]15[60]-[65]100[999]21ade.jpg H:\1\PICTURES\some\

我有以下文件:

H:\1\PICTURES\some\dir\sdir1[60]19\[0]-[30]15[60]-[65]-[999]abc.jpg
H:\1\PICTURES\some\dir\sdir200\ssdir5[60]22\[0]20[30]15[60]--[65]22[999]abcd.jpg
H:\1\PICTURES\some\dir\sdir20[60]218\[0]-[30]15[60]-[65]100[999]21ade.jpg
H:\1\PICTURES\some\dir\sdir33[60]335\[0]-[30]15[60]-[65]31[999]2ade.jpg
H:\1\PICTURES\some\dir\sdir5[60]26\[0]-[30]15[60]-[65]-[999]1abc4.jpg
H:\1\PICTURES\some\dir\sdir8000[60]525\[0]-[30]15[60]-[65]-[999]abc4.jpg
H:\1\PICTURES\some2\dir\sdir7[61]12\[0]-[30]15[61]-[65]-[999]abc5.jpg
H:\1\PICTURES\some2\dir\sdir33[61]25\[0]-[30]15[61]-[65]-[999]ffc5.jpg

我想在以下位置使用批处理对其进行重命名:

H:\1\PICTURES\some\dir\sdir1[60]19\[0]-[30]15[60]19[65]-[999]abc.jpg
H:\1\PICTURES\some\dir\sdir200\ssdir5[60]22\[0]20[30]15[60]22[65]22[999]abcd.jpg
H:\1\PICTURES\some\dir\sdir20[60]218\[0]-[30]15[60]218[65]-[999]21ade.jpg
H:\1\PICTURES\some\dir\sdir33[60]335\[0]-[30]15[60]335[65]31[999]2ade.jpg
H:\1\PICTURES\some\dir\sdir5[60]26\[0]-[30]15[60]26[65]-[999]1abc4.jpg
H:\1\PICTURES\some\dir\sdir8000[60]525\[0]-[30]15[60]525[65]-[999]abc4.jpg
H:\1\PICTURES\some2\dir\sdir7[61]12\[0]-[30]15[61]12[65]-[999]abc5.jpg
H:\1\PICTURES\some2\dir\sdir33[61]25\[0]-[30]15[61]25[65]-[999]ffc5.jpg

文件夹名称的最后一部分(以
[
开头)必须成为字符串,该字符串将替换新文件名中以相同数字开头的字符串

因此,在第一个示例中,将[60]-替换为[60]19

路径、字符串和文件名的长度是可变的

我知道解决方案是使用
令牌
delims
,但我没有找到在所有情况下如何获得正确的字符串


编辑1

到目前为止,我有:

@ECHO OFF
SETLOCAL
setlocal EnableDelayedExpansion

SET "sourcedir=H:\1\Pictures\some\dir\sdir1 [60]19"

FOR /f "delims=" %%a IN (    
'dir /s /b /a-d "%sourcedir%\*" '
) DO (

set newstr=%sourcedir:~-2,2%  
ren "%%a" ????"(%newstr%)"????????????????????????????????
)
我有以下问题:

  • 这些文件已重命名,但具有
    ()
    而不是
    19

  • 路径是硬编码的,而不是变量。
    (H:\1\Pictures`+变量用于某些\dir\sdir1[60]19,某些\dir\sdir5[60]26…)

  • set newstr=%sourcedir:~-2,2%
    中,我设置了路径名的最后2个位置。可能需要有3个位置,例如[60]225

  • 在重命名命令中,我使用???而不是变量,这不是用于元素的变量位置或长度的解决方案


  • 编辑2

    我解决了第一个问题。
    set newstr=%sourcedir:~-2,2%
    不起作用

    所以我改变了

    ren "%%a" ????"(%newstr%)"????????????????????????????????
    


    但是如何知道
    %sourcedir%
    中必须有2或3个数字?

    这可以通过以下批次代码来完成:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    
    set "ListFile=%TEMP%\FilesNotRenamed.tmp"
    del "%ListFile%" 2>nul
    set "FileCount=0"
    
    for /F "delims=" %%A in ('dir /A-D /B /S "H:\1\PICTURES\*.jpg" 2^>nul') do (
    
        set "FileName=%%~nxA"
        set "FilePath=%%~dpA"
        set "FilePath=!FilePath:~0,-1!"
    
        for /F "delims=" %%B in ("!FilePath!") do (
            for /F "tokens=2* delims=[]" %%C in ("%%~nxB") do (
    
                set "FileName=!FileName:[%%C]--=[%%C]%%D!"
                if not exist "%%~dpA!FileName!" (
                    ren "%%A" "!FileName!"
                ) else if not "%%~nxA" == "!FileName!" (
                    set /A FileCount+=1
                    echo %%A>>"%ListFile%"
                )
    
            )
        )
    )
    
    if exist "%ListFile%" (
        set "PluralS=s"
        if %FileCount% == 1 set "PluralS="
        echo The following %FileCount% file!PluralS! could not be renamed because a
        echo file with target name exists already in same directory:
        echo/
        type "%ListFile%"
        del "%ListFile%"
        echo/
        pause
    )
    
    endlocal
    
    最外层的FOR运行命令DIR,该命令由于
    /B
    (裸格式)和
    /S
    (在所有子目录中也递归搜索)而输出在目录
    H:\1\PICTURES
    及其所有子目录中找到的*.jpg文件的所有名称,其完整路径从未包含在双引号中,忽略了碰巧以
    .jpg
    结尾的目录(不太可能,但谁知道呢)

    DIR输出示例:

    H:\1\PICTURES\some\dir\sdir5 [60]26\[0]--[30]15 [60]--[65]--[999]1abc4.jpg
    H:\1\PICTURES\some\dir\sdir1 [60]19\[0]--[30]15 [60]--[65]--[999]abc.jpg
    H:\1\PICTURES\some\dir\sdir8000 [60]525\[0]--[30]15 [60]--[65]--[999]abc4.jpg
    H:\1\PICTURES\some\dir\sdir20 [60]218\[0]--[30]15 [60]--[65]100[999]21ade.jpg
    H:\1\PICTURES\some\dir\sdir33 [60]335\[0]--[30]15 [60]--[65]31[999]2ade.jpg
    H:\1\PICTURES\some\dir\sdir200\ssdir5 [60]22\[0]20[30]15 [60]--[65]22[999]abcd.jpg
    H:\1\PICTURES\some2\dir\sdir7 [61]12\[0]--[30]15 [61]--[65]--[999]abc5.jpg
    H:\1\PICTURES\some2\dir\sdir33 [61]25\[0]--[30]15 [61]--[65]--[999]ffc5.jpg
    H:\1\PICTURES\some2\dir\sdir33 [61]25\[0]--[30]15 [61]25[65]--[999]ffc5.jpg
    
    2^>nul
    导致将由DIR输出的错误消息重定向到STDERR设备nul以在根本找不到*.jpg文件时将其抑制。在执行命令时,字符
    必须转义为
    ^
    DIR并且尚未对命令行进行解析,这将导致由于语法错误而退出批处理执行

    下一步,最外层的将对该文件名列表进行逐行处理,其中每个文件名和路径都分配给循环变量
    A
    。默认情况下,
    delims=
    禁用在空格/制表符上拆分字符串

    文件扩展名为当前文件的文件名分配给环境变量
    FileName
    ,文件路径分配给环境变量
    FilePath

    接下来,文件路径末尾的反斜杠将从文件路径中删除,这对于下一个对于非常重要

    在命令块中定义/修改的环境变量,以第一个
    开头,以匹配的
    结尾)必须使用延迟扩展在同一命令块中引用
    ,因为Windows command processor在第一次执行整个命令块之前,在解析整个命令块时已将所有%variable%替换为环境变量的值。这解释了
    !FileName!
    !FilePath!
    的用法,最后一次是也可以使用
    !PluralS!
    代替上面批处理代码中的
    %FileName%
    %FilePath%
    %PluralS%

    下一步需要存储当前文件的文件夹名称。目录名称是使用另一个FOR获取的,它解析文件路径,而不是以反斜杠结尾。在
    FilePath
    中最后一个反斜杠后的字符串引用为
    %~nxB
    …文件名和文件扩展名,在这里是直接的解析的字符串是以文件夹名而不是文件名结尾的文件路径

    在外部单词中
    %%
    
    H:\1\PICTURES\some\dir\sdir5 [60]26\[0]--[30]15 [60]--[65]--[999]1abc4.jpg
    H:\1\PICTURES\some\dir\sdir1 [60]19\[0]--[30]15 [60]--[65]--[999]abc.jpg
    H:\1\PICTURES\some\dir\sdir8000 [60]525\[0]--[30]15 [60]--[65]--[999]abc4.jpg
    H:\1\PICTURES\some\dir\sdir20 [60]218\[0]--[30]15 [60]--[65]100[999]21ade.jpg
    H:\1\PICTURES\some\dir\sdir33 [60]335\[0]--[30]15 [60]--[65]31[999]2ade.jpg
    H:\1\PICTURES\some\dir\sdir200\ssdir5 [60]22\[0]20[30]15 [60]--[65]22[999]abcd.jpg
    H:\1\PICTURES\some2\dir\sdir7 [61]12\[0]--[30]15 [61]--[65]--[999]abc5.jpg
    H:\1\PICTURES\some2\dir\sdir33 [61]25\[0]--[30]15 [61]--[65]--[999]ffc5.jpg
    H:\1\PICTURES\some2\dir\sdir33 [61]25\[0]--[30]15 [61]25[65]--[999]ffc5.jpg
    
    sdir5 [60]26
    sdir1 [60]19
    sdir8000 [60]525
    sdir20 [60]218
    sdir33 [60]335
    ssdir5 [60]22
    sdir7 [61]12
    sdir33 [61]25
    sdir33 [61]25
    
    60   26
    60   19
    60   525
    60   218
    60   335
    60   22
    61   12
    61   25
    61   25