>我在一个文件夹中有几个文件,名称如下
"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-N
,prefix
模式的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。