【发布时间】:2015-08-27 15:30:09
【问题描述】:
我正在尝试重命名很多文件。我只想将扩展名从“.pdf.OCR.pdf”更改为“.pdf” 到目前为止,我得到了以下代码
rem for /r myPDFfolder %%i in (*.pdf.OCR.pdf) do ren "%%i" "%%~ni.pdf"
但它似乎不适用于具有多个点的扩展程序——我做错了什么?
【问题讨论】:
标签: windows file batch-file rename
我正在尝试重命名很多文件。我只想将扩展名从“.pdf.OCR.pdf”更改为“.pdf” 到目前为止,我得到了以下代码
rem for /r myPDFfolder %%i in (*.pdf.OCR.pdf) do ren "%%i" "%%~ni.pdf"
但它似乎不适用于具有多个点的扩展程序——我做错了什么?
【问题讨论】:
标签: windows file batch-file rename
扩展名是最后一个点之后的文件名部分。
使用字符串替换去除不需要的部分:
setlocal enableDelayedExpansion
for /f "eol=* delims=" %%i in ('dir /s /b "r:\*.pdf.OCR.pdf"') do (
set "name=%%~nxi"
ren "%%i" "!name:.pdf.OCR=!"
)
附: dir 的解析用于使代码更加健壮,以防不同的文本被剥离,这可能会改变排序顺序并导致 for 处理文件两次或更多次。
【讨论】:
!file:.pdf.OCR.pdf=.pdf! 来完全符合原来的问题...
set name=%%~ni 和 ren "%%i" "!name:.OCR=!",所以代码已经是多余的了。
" 放在整个set 表达式周围,以避免文件中出现^ 或& 等特殊字符的麻烦姓名;我建议通过dir /S /B /A:-D 枚举目录并通过for /F 解析其输出,而不是使用for /R 以确保枚举目录树before 遍历它;由于您正在修改for /R 正文中的树,因此可能会出现冲突(请参阅我的post about that topic)...
dir 使代码更健壮地满足其他人的需求。但是幸运的是在这种特殊情况下不需要dir,因为新文件名不会改变排序顺序。
*.pdf.ocr.pdf 文件掩码匹配。
不需要批处理文件。命令提示符中的一个中等长度的一行可以解决问题。
如果您知道所有匹配 *.pdf.ocr.pdf 的文件都具有这种确切的大小写:.pdf.OCR.pdf,那么您可以从命令行使用以下命令:
for /r "myPDFfolder" %F in (.) do @ren "%F\*.pdf.ocr.pdf" *O&ren "%F\*.pdf.o" *f
第一次重命名删除了结尾的.pdf,第二次删除了.OCR。上述工作是因为目标掩码中的*O 通过最后一次出现的大写O 保留原始文件名中的所有内容,而*f 通过最后一次出现的小写f 保留。请注意,源掩码中的字符不区分大小写。您可以在How does the Windows RENAME command interpret wildcards?
如果.pdf.ocr.pdf 的情况可以变化,那么上面的内容将会惨遭失败。但是仍然有一个命令行可以从命令行工作:
for /r "myPDFfolder" %F in (*.pdf.ocr.pdf) do @for %G in ("%~nF") do @ren "%F" "%~nG"
%~nF 删除了最后一个 .pdf,%~nG 删除了 .OCR,留下了所需的 .pdf 扩展名。
您不必担心文件被重命名两次,因为重命名后的结果将不匹配 *.pdf.ocr.pdf,除非原始文件看起来像 *.pdf.ocr.pdf.ocr.pdf。
如果您认为您将来可能想要频繁地重命名具有复杂模式的文件,那么您应该查看JREN.BAT - 一个正则表达式重命名实用程序。它是纯脚本(混合 JScript/批处理),可以在 XP 以后的任何 Windows 机器上本地运行。完整的文档嵌入在脚本中。
假设 JREPL.BAT 位于您的 PATH 中列出的文件夹中,那么以下简单命令将从命令行运行,仅重命名与搜索字符串中的大小写匹配的文件:
jren "(\.pdf)\.OCR\.pdf$" $1 /s /p "myPDFfolder"
如果你想在匹配时忽略大小写,但又想强制扩展为小写,那么:
jren "\.pdf\.ocr\.pdf$" ".pdf" /i /s /p "myPDFfolder"
【讨论】:
替代解决方案,不带delayed expansion(删除ECHO 以实际重命名任何文件):
@echo off
rem iterate over all matching files:
for /F "delims=" %%A in (
'dir /S /B /A:-D "myPDFfolder\*.pdf.OCR.pdf"'
) do (
rem "%%~nA" removes last ".pdf"
for /F %%B in ("%%~nA") do (
rem "%%~nB" removes ".OCR" part
for /F %%C in ("%%~nB") do (
rem "%%~nC" removes remaining ".pdf"
ECHO ren "%%~fA" "%%~nC.pdf"
) & rem next %%C
) & rem next %%B
) & rem next %%A
注意:目录树被枚举之前 for 遍历它,否则,某些项目可能会被跳过或尝试重命名两次(请参阅this post关于那个问题)。
【讨论】: