.Bat 文件删除文件名中特定三字母代码之后的所有文本

问题描述 投票:0回答:1

在我的工作中,我们经常遇到这样的情况:我们有数百个输出的 PDF 的文件夹。这些都具有相同的命名方案:

[数字/文本字符串]-XYZ [更多文本]

它们在初始文档标题后都有一个 3 个字母的代码 - 它并不总是 XYZ,它可以是任意 3 个大写字母。

为了提交这些文件,需要缩小文件名,3 个字母代码之后的所有内容都需要删除,之前的所有内容都需要保留。代码之前的字符串和代码之后的文本的内容和字符数都不同,因此代码在名称中的位置不一致。

目前的解决方案是手动检查并删除文件名末尾的文本,这需要很长时间,我想一定有更好的解决方案。

我理想中想要的是一个 .Bat 文件,我(或我的同事)可以将其放入任何给定的文件夹中并运行它以批量重命名文件。我自己做了一些测试,但我无法完全让它按照我想要的方式工作。

这就是我现在所拥有的:

@echo off
setlocal enabledelayedexpansion

echo Starting the renaming process...

REM Loop through all PDF files in the current directory
for %%f in (*.pdf) do (
    set "filename=%%~nf"
    set "extension=%%~xf"

    REM Debug: Show the current filename being processed
    echo Processing: %%f

    REM Check if "XYZ" is in the filename
    echo !filename! | findstr /C:"XYZ" >nul
    if !errorlevel! equ 0 (
        echo Found "XYZ" in: !filename!

        REM Retain everything up to and including "XYZ"
        for /f "tokens=1 delims=XYZ" %%a in ("!filename!") do (
            set "newname=%%a"
        )
        
        REM Append "XYZ" to the new name
        set "newname=!newname!XYZ"

        REM Debug: Show the new name before renaming
        echo New name will be: "!newname!!extension!"

        REM Check for duplicates and rename
        if not exist "!newname!!extension!" (
            ren "%%f" "!newname!!extension!"
            echo Renamed "%%f" to "!newname!!extension!"
        ) else (
            echo Skipping "%%f" because a file named "!newname!!extension!" already exists.
        )
    ) else (
        echo "XYZ" not found in: !filename!
    )
)

REM Pause to see the output
echo Finished processing. Press any key to exit.
pause

endlocal

我知道这很糟糕,并希望因为我糟糕的脚本而受到批评,但这实际上工作得很好。它找到代码并删除其后面的内容。

我遇到的问题是,如果代码之前的字符串包含代码中的任何字母,那么它们也会被删除。它也感觉很笨重,作为一个不太精通这方面的人,我认为寻求建议是明智的。

非常感谢您能给我的任何帮助或提示。

附注我知道 Windows Powershell 是一个更好的工具。然而,由于某种原因,它在我们的系统上被阻止了。

windows batch-file directory rename explorer
1个回答
0
投票
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"

SET "targetstring=XYZ"
SET "requiredextension=pdf"

FOR %%e IN ("%sourcedir%\*%targetstring%*.%requiredextension%") DO (
 rem %%e has the full name of the file detected
 ECHO processing %%e
 
 rem ensure targetstring found is upper-case
 SET "originalname=%%~ne"
 ECHO %%~ne |FINDSTR /L /c:"%targetstring%" >NUL
 IF ERRORLEVEL 1 (
  ECHO skipping %%~nxe - does NOT contain upper-case "%targetstring%"
 ) ELSE (
  CALL :subsuconly
  IF EXIST "%sourcedir%\!newname!%%~xe" (
   ECHO Cannot RENAME "%%~nxe" to "!newname!%%~xe" as "!newname!%%~xe" already exists
  ) ELSE (
   ECHO Renaming "%%~nxe" to "!newname!%%~xe"
   ECHO REN "%%e" "!newname!%%~xe"
  )
 )
)

GOTO :EOF

::
:: Substitute only the upper-case targetstring
:subsuconly
SET "newname="
:: first 3 characters of copyname are targetstring?
:subsloop
IF "%originalname:~0,3%"=="%targetstring%" SET "newname=%newname%%targetstring%"&GOTO :eof
SET "newname=%newname%%originalname:~0,1%"
SET "originalname=%originalname:~1%"
GOTO subsloop

您的问题是

delims
字符串不是字符串,而是一组作为分隔符的字符,因此您的分隔符是
X
Y
Z
,而不是字符串
XYZ

通过包含文件掩码

*%targetstring%*.%requiredextension%
for
将仅选择包含
XYZ
并以
pdf
结尾的文件名。这可以避免出现不适合面具的混乱名称。

但是,匹配不区分大小写,因此它会检测例如

xyz

因此,检测所需的字符串。如果找到字符串,

findstr
将错误级别设置为
0
IF ERRORLEVEL 1
表示
IF ERRORLEVEL 1 OR GREATER

如果找到字符串is,则通过简单地累加原始名称开头的每个字符,直到原始名称中剩余字符串的前3个字符是所需的大写字符串来生成新名称。考虑“zelxyzloXYZ World.pdf”,其中字符串

xyz
出现在
XYZ

之前

然后尝试重命名。请注意,

REN
命令已解除,只需按
echo
即可进行验证。删除
echo
即可激活(验证后自然)。

© www.soinside.com 2019 - 2024. All rights reserved.