批处理脚本 - 重命名文件,删除变量前缀和后缀



>我在一个文件夹中有几个文件,名称如下

"prefix (S-N 12RE3123) suffix.pdf"

我想将它们重命名为 仅"12RE3123.pdf" ,删除前缀和后缀。 问题是前缀和后缀的长度/字符各不相同,所以我不能通过删除第一个/最后一个 xx 个字符来重命名,而必须使用唯一的通用性,其中只有后面括号内的字符"S-N"是要保留的字符。

有一种特殊情况,其中一些序列号被命名为 WD-12RE3123 ,我也需要删除WD-。 如果我必须手动完成,那么这样的方法并不多,所以不会是世界末日,但将其自动化会很好。 我想也许在删除前缀/后缀后做一个 if 语句来检查前 3 个字符是否匹配WD-然后删除它们(如果为 true),但我不确定实现。

我仍然是批处理或 vbscript 的新手,所以我想知道这是否可以在其中任何一个中完成。 批处理具有" REN "方法来重命名文件,但由于最终名称取决于当前名称是什么,我不确定如何设置分隔符或如何处理。

任何协助将不胜感激。

这是您请求的简单解决方案。它依赖于以下事实:

  • prefix部分不包含任何括号(或单独)suffix可能);
  • 序列号不包含任何括号(或单独);
  • 没有重复的序列号,在删除电位WD-字符串方面也是如此;

这是代码(在对目标文件夹中的文件测试代码后,您需要删除大写ECHO命令以实际重命名文件):

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Set constants here:
set "LOCATION=.test"
set "PATTERN=*.pdf"
set STRINGS="S-N " "WD-"
cd /D "%LOCATION%"
for /F "eol=| delims=" %%K in ('dir /B "%PATTERN%"') do (
    for /F "eol=| tokens=2 delims=()" %%L in ("%%~nK") do (
        set "NAME=%%L"
        setlocal EnableDelayedExpansion
        for %%J in (%STRINGS%) do (
            if "!NAME!"=="%%~J!NAME:*%%~J=!" (
                set "NAME=!NAME:*%%~J=!"
            )
        )
        ECHO ren "%%~fK" "!NAME!%%~xK"
        endlocal
    )
)
endlocal
exit /B

工作原理:

  • 第一部分指定文件夹位置、文件模式和要删除的字符串(在提取()中的部分后); 根据您的需要调整值;
  • 有几个嵌套的for循环;最外面的一个只是迭代与给定模式匹配的所有文件(它基本上读取和解析应用于给定文件的dir命令的输出,并循环返回的项目;与标准的for循环相反,这种for /F方法确保在循环开始迭代之前读取整个文件夹, 这在修改枚举的文件夹内容时是必要的,就像我们在这里通过重命名文件所做的那样;另请参阅有关该问题的此线程);
    • 下一个for /F循环提取感兴趣的文件名部分,即第一对括号之间的所有内容,并将其存储在变量NAME中; 此循环仅对每个文件迭代一次;
      • 这是另一个for循环,它遍历STRINGS变量中的所有项目;
        • if 子句检查当前STRINGS项是否出现在NAME值的最开头;如果是,则将其删除,否则不出现;这只是一个安全查询,因为序列号可能还可能包含中间或末尾的给定STRINGS项(例如, 123-WD-45A );
      • 此时,将执行重命名(当然,在删除ECHO之后);
      • 延迟扩展的切换旨在避免文件名中某些特殊字符出现问题;

这是另一个脚本,它使用更复杂的方法来提取文件名的有趣部分。它依赖于以下事实:

  • 文件名中只有一个子字符串(S-N
  • 空格
  • 序列号后跟一个);
  • 序列号不包含任何括号(或单独);
  • 没有重复的序列号,在删除电位WD-字符串方面也是如此;

代码如下所示:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Set constants here:
set "LOCATION=.test"
set "PATTERN=*.pdf"
set "FILTER=(S-N [^()][^()]*)"
set "IDENTIFYER=S-N "
set STRINGS="WD-"
cd /D "%LOCATION%"
for /F "eol=| delims=" %%K in ('
    dir /B "%PATTERN%" ^| findstr /I /R /C:"%FILTER%"
') do (
    set "NAME=%%K"
    setlocal EnableDelayedExpansion
    set "NAME=!NAME:*(%IDENTIFYER%=!"
    for /F "eol=| tokens=1 delims=)" %%L in ("!NAME!") do (
        setlocal DisableDelayedExpansion
        set "NAME=%%L"
        setlocal EnableDelayedExpansion
        for %%J in (%STRINGS%) do (
            if "!NAME!"=="%%~J!NAME:*%%~J=!" (
                set "NAME=!NAME:*%%~J=!"
            )
        )
        ECHO ren "%%~fK" "!NAME!%%~xK"
        endlocal
        endlocal
    )
    endlocal
)
endlocal
exit /B

基本上,这个脚本的工作方式与上面的脚本类似,有一些偏差:

  • 第一部分指定了文件名过滤器和序列号识别器(S-N);
  • 最外层for循环中的dir命令通过管道传输到findstr命令中,以过滤掉不包含(S-N)的文件以及介于两者之间的字符串(不包含(/))已经在开头;
    • 删除(S-N的部分和之前的所有内容,结果存储在NAME中;
    • 下一个 for /F 循环从 NAME 值中提取所有内容,但不包括第一个),该值构成了感兴趣的文件名部分; 此循环仅对每个文件迭代一次;
      • 这是另一个for循环,它遍历 STRINGS 变量中的所有项目,该变量不包含此处的S-N部分,因为它之前已经被删除; 此循环中的其余部分与上述脚本中的相同;
      • 此时,将执行重命名(当然,在删除ECHO之后);
@ECHO Off
SETLOCAL
SET "sourcedir=U:sourcedir"
FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%*(*)*.*" '
 ) DO (
 FOR /f "tokens=1,2delims=()" %%c IN ("%%a") DO (
  FOR /f "tokens=1-3delims=- " %%m IN ("%%d") DO (
   IF "%%o"=="" (ECHO(REN "%sourcedir%%%a" "%%n%%~xa"
   ) ELSE (
    ECHO(REN "%sourcedir%%%a" "%%o%%~xa"
   )
  )
 )
)
GOTO :EOF

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

所需的 REN 命令仅用于测试目的ECHO验证命令正确后,将ECHO(REN更改为REN以实际重命名文件。

将与掩码"()."匹配的每个文件名应用于%%a

使用()作为分隔符进行标记化,以便括号中的部分%%d使用 - 作为分隔符重新标记化,以便%%n模式所需的数字S-Nprefix模式的WD-

显示重命名行。

注意:如果jren /?部分不包含括号并且括号部分与描述完全一致,则这应该有效。

Magoo 和 aschipfl 都提供了良好的纯批次解决方案。

发现为每个复杂的重命名任务开发自定义批处理脚本很乏味,这就是我编写 JREN.BAT - 一个正则表达式查找/替换重命名实用程序的原因。JREN.BAT 是纯脚本(混合 JScript/batch),从 XP 开始在任何 Windows 机器上本机运行。完整的文档可通过命令行通过 jren /?? 获得,或使用 /T 获取分页帮助。

使用 JREN.BAT,解决方案非常简单(未经测试):

jren "^.*((?:S-N (?:WD-)?)(.+?)).*" "$1.jpg" /fm *.jpg

如果我弄错了正则表达式,它可以很容易地修复。您可能应该添加 CC_69 选项以首先在测试模式下运行该命令,然后在一切正常时将其删除。

如果将命令放在批处理脚本中,则必须使用 CALL JREN。

最新更新