用于重命名文件的Windows批处理脚本

时间:2017-06-22 07:08:08

标签: windows batch-file

我在Windows文件夹中有很多文件。这些文件名也包含很多下划线。 E.g:

ad_iod_errr_opp12.txt  
ghff_jjk56.txt  
opr_sdr_ot_wrr_12ee.txt  

我想重命名这些文件,以便删除最后一个下划线及其后面的所有内容,并按如下方式重命名文件:

ad_iod_errr.txt
ghff.txt
opr_sdr_ot_wrr.txt

注意:下划线的数量会有所不同。某些文件名可能只有一个下划线,而其他文件名最多可能有8个下划线。我正在寻找一个Windows批处理脚本,可以完成这个技巧而不是PowerShell命令。

这是我目前用来重命名文件的代码,因为文件名中只有一个下划线:

@ECHO OFF 
SETLOCAL 
cd C:\Users\ambika.narayan.rao\JenkinsWorkspace 
SET "fname=*.txt" 
FOR %%i IN ("%fname%") DO FOR /f "delims=_" %%j IN ("%%i") DO ren "%%~i" "%%~j%%~xi" 
GOTO :EOF

2 个答案:

答案 0 :(得分:1)

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\*_*.txt" '
 ) DO (
 SET "filename=%%a"
 set "partsname=!filename:_= _!"
 FOR %%b IN (!partsname!) DO SET "newname=!filename:%%b=!%%~xa"
 ECHO REN "%sourcedir%\%%a" "!newname!"
)

GOTO :EOF

您需要更改sourcedir的设置以适合您的具体情况。

为了测试目的,所需的REN命令仅为ECHO在您确认命令正确后,将ECHO(REN更改为REN以实际重命名文件。

对与掩码匹配的所有文件名执行目录扫描。找到每个名称后,使用延迟展开,将名称指定为filename,然后将每个_替换为 Space _

使用简单的fornewname分配给原始文件名,同时删除_string(替换为 nothing )并使用{{添加回扩展名1}}。分配给%%~xa的最后一个字符串将为%%b,因此分配给_laststring.ext的值将符合处理要求,因此请重命名该文件。

答案 1 :(得分:0)

这是我在another answer中发布的修改过的脚本,依赖于一个很好的黑客来删除由某个字符分隔的字符串的最后一部分 - 在这种情况下是下划线_。请注意,如果任何文件的名称中包含感叹号!,则会失败。所以这是代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=%~dp0."
set "_MASK=*_*.txt"

rem // Enumerate all matching files:
for /F "delims= eol=|" %%F in ('dir /B /A:-D "%_SOURCE%\%_MASK%"') do (
    rem // Store current file name and extension:
    set "FILE=%%~nF" & set "FEXT=%%~xF"
    rem // Call sub-routine that removes the last `_`-separated part:
    call :GET_LAST_ITEM LAST RMND "%%~nF"
    rem // Enable delayed expansion to be able to read the variables:
    setlocal EnableDelayedExpansion
    rem /* Actually rename current file: */
    ECHO ren "!FILE!!FEXT!" "!RMND!!FEXT!"
    endlocal
)

endlocal
exit /B


:GET_LAST_ITEM  rtn_last  rtn_without_last  val_string
    ::This function splits off the last `_`-separated item of a string.
    ::Note that exclamation marks must not occur within the given string.
    ::PARAMETERS:
    ::  rtn_last            variable to receive the last item
    ::  rtn_without_last    variable to receive the remaining string
    ::  val_string          original string
    setlocal EnableDelayedExpansion
    set "STR=_%~3"
    set "PRE=" & set "END=%STR:_=" & set "PRE=!PRE!_!END!" & set "END=%"
    endlocal & set "%~1=%END%" & set "%~2=%PRE:~2%"
    exit /B

为了能够正确处理带有感叹号的文件名,这里有一个不同的方法:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=%~dp0."
set "_MASK=*_*.txt"

rem // Enumerate all matching files:
for /F "delims= eol=|" %%F in ('dir /B /A:-D "%_SOURCE%\%_MASK%"') do (
    rem // Store current file name and extension:
    set "FILE=%%~nF" & set "FEXT=%%~xF"
    rem // Initialise some variables:
    set "NAME=" & set "ITEM="
    rem // Toggle delayed expansion to not lose `!` in file names:
    setlocal EnableDelayedExpansion
    rem /* Loop through all partial file names separated by `_`; since every
    rem    `_` is replaced by `" "` and the whole string is enclosed in `""`,
    rem    we effectively get a list of quoted file name parts, which were
    rem    originally separated from each other by `_`: */
    for %%I in ("!FILE:_=" "!") do (
        rem /* Rebuild file name but delayed by one name part; the `for /F` loop
        rem    iterates once and transports the result beyond `endlocal`: */
        for /F "delims= eol=|" %%E in ("!NAME!!ITEM!_") do (
            endlocal
            set "NAME=%%E"
        )
        rem // Belatedly store currently iterated file name part:
        set "ITEM=%%~I"
        setlocal EnableDelayedExpansion
    )
    rem /* Actually rename current file; superfluous leading and trailing `_`
    rem    are removed from the rebuilt file name: */
    ECHO ren "!FILE!!FEXT!" "!NAME:~1,-1!!FEXT!"
    endlocal
)

endlocal
exit /B

成功测试脚本后,删除大写ECHO命令以实际重命名任何文件!