搜索特定扩展名的文件名并删除特殊字符

时间:2014-08-25 18:34:19

标签: batch-file for-loop rename batch-rename

我正在尝试编写一个补丁文件,该文件将执行以下操作:

  • 搜索所有* .pdf和* .xls文件的w:\。有许多目录和子目录要搜索。
  • 我需要搜索文件名并替换以下内容。并非每个文件名都包含这些不需要的字符。
    • 查找&并替换为和
    • 找到#并删除#
    • 查找“LTD。”(在“L”之前有一个空格)并将其删除。
  • 如果已进行上述任何更改,请重命名该文件。
  • 输出所有已更改文件的文件。

我遇到了一些问题因此我的帖子在这里。我已经能够将此代码与本网站上的其他帖子拼凑在一起。这就是我到目前为止所拥有的。对我来说很容易,因为我在大学做过任何编程已有18年了。

我正在使用JP Software的一个名为Take Command的程序,所以我可以使用某种调试器并试图弄清楚我做错了什么。

感谢您的帮助。

@Echo OFF
set /A xcount=0
set root=c:\clients
Set logfilename=Changed.txt
cd %root%

for /f "delims=" %%a in ('dir /a:-d /o:n /b /s *.pdf *.xls') do call :next "%%a"
echo. >> %root%\%logfilename%
echo End of file > %root%\%logfilename%
pause
GOTO:EOF

:next
    set "current=%~nx1"
    set "newname=%~nx1"
    set "newname=%newname:&=and%"
    set "newname=%newname:#=%"
    set "newname=%newname: LTD.=%"
    set "newname=%newname:%=%"
    set "newname=%newname::=%"

If "%current%" == "%newname%" goto nope
    SET /A xcount+=1
    ren "%current%" "%newname%"
    echo "%current%" "%newname%"
    echo %xcount% - "%current%" "%newname%" > %root%\%logfilename%
:nope

2 个答案:

答案 0 :(得分:1)

我发现了两个主要问题:

1)您的REN命令必须具有源文件的完整路径。您只提供名称和扩展名。

2)看起来你也试图删除%个字符。正常扩张无法做到这一点 - 需要延迟扩张。此外,%必须加倍。

我发现了一些效率低下的问题:

1)不需要任何CALL或GOTO。两者都相对较慢。一切都可以在一个循环中使用括号完成。如果要处理的文件很多,性能差异可能会很大。请注意,使用已在块中设置的变量需要延迟扩展。

2)反复打开和关闭日志文件以追加更多信息的速度很慢。将整个块括在括号中并仅重定向一次会更有效。

3)您正试图从名称中删除:。这不是必需的,因为Windows文件名不能包含:

4)您已将当前目录设置为根目录,因此重定向时无需包含路径。

以下是我未经测试的解决方案的几点注意事项:

1)在循环内打开和关闭延迟扩展,以保护文件名或路径中可能出现的任何!。如果变量包含!并且启用了延迟扩展,则变量在扩展时会损坏。

2)我使用echo(代替echo.来回显空行。这种语法看起来很奇怪,但总是有效。 echo. synyax在某些不明确的条件下会失败。

3)我使用CD的PUSHD insead将当前目录设置为root。如果要更改当前音量(例如D:到C:),如果没有/ D选项,CD将无法正常工作

4)外部块将非标准/未使用的文件句柄重定向到日志文件。然后在块中,特定输出被重定向到日志文件句柄。这样做是为了不必重复打开日志文件,重新定位到结束和关闭日志文件。其他输出转到正常标准输出。

@echo off
setlocal disableDelayedExpansion
set /a xcount=0
set "root=c:\clients"
Set "logfile=Changed.txt"
pushd "%root%"

3>"%logfile%" (
  for /f "delims=" %%F in ('dir /a:-d /o:n /b /s *.pdf *.xls') do (
    set "file=%%~fF"
    set "old=%%~nxF"
    set "new=%%~nxF"
    setlocal enableDelayedExpansion
    set "new=!new:&=and!"
    set "new=!new:#=!"
    set "new=!new: LTD.=!"
    set "new=!new:%%=!"
    if "!new!" neq "!old!" (
      set /a xcount+=1
      ren "!file!" "!new!"
      echo "!file!" "!new!"
      echo !xcount! - "!file!" "!new!">&3
    )
    endlocal
  )
  echo(>&3
  echo End of file>&3
)
popd
pause
exit /b

注意 - 上述解决方案按照您的说明实施规则。但有一个问题。像"Acme LTD.pdf"这样的名称将重命名为"Acmepdf"


更新

自回答以来,我编写了一个名为JREN.BAT的便捷工具,可以非常简单地解决问题。该实用程序通过执行正则表达式搜索并替换文件名来执行重命名操作。 JREN.BAT是一个混合JScript /批处理脚本,可以在XP以后的任何Windows机器上本机运行。

我已经稍微改进了你的规则,以便在扩展名之前发生的LTD保留扩展名的点,并且名称中间发生的LTD.会删除该点。

假设您在当前目录中有JREN.BAT,或者更好,在PATH中的某个地方,那么以下脚本应该可以解决问题。

<强> renFiles.bat

@echo off
call jren "(&)|(#|%| LTD(?=\.[^.]*$)| LTD\.)" "$1?'and':''" /i /s /j /fm "*.pdf|*.xls" %1 >rename.log
type rename.log

我建议使用/T选项在测试模式下运行上述内容。它将简单地列出建议的重命名操作,而不实际重命名任何内容。

renFiles /T

验证一切正常后,再次运行/T

答案 1 :(得分:0)

给定目录u:\sourcedir\t w o

 Volume in drive U has no label.
 Volume Serial Number is 0460-0000

 Directory of u:\sourcedir\t w o

14/12/2014  00:05    <DIR>          .
14/12/2014  00:05    <DIR>          ..
14/12/2014  00:28                 0 dum myfile2.txt
14/12/2014  00:28                 0 file1.xls
14/12/2014  00:28                 0 file2.xls
14/12/2014  00:28                 0 file3.xls
14/12/2014  00:28                 0 amper&1.pdf
14/12/2014  00:28                 0 amper&2.pdf
14/12/2014  00:28                 0 amper&3.pdf
14/12/2014  00:28                 0 hash#1.xls
14/12/2014  00:28                 0 hash#2.xls
14/12/2014  00:28                 0 hash#3.xls
14/12/2014  00:28                 0 LTD LTD 1.pdf
14/12/2014  00:28                 0 LTD LTD 2.pdf
14/12/2014  00:28                 0 LTD LTD 3.pdf
14/12/2014  00:28                 0 lower ltd 1.pdf
14/12/2014  00:28                 0 lower ltd 2.pdf
14/12/2014  00:28                 0 lower ltd 3.pdf
14/12/2014  00:28                 0 ALL#& LTD 1.pdf
14/12/2014  00:28                 0 ALL#& LTD 2.pdf
14/12/2014  00:28                 0 ALL#& LTD 3.pdf
14/12/2014  00:28                 0 shriek!hello!1.pdf
14/12/2014  00:28                 0 shriek!hello!2.pdf
14/12/2014  00:28                 0 shriek!hello!3.pdf
14/12/2014  00:28                 0 pcnt%hello%1.pdf
14/12/2014  00:28                 0 pcnt%hello%2.pdf
14/12/2014  00:28                 0 pcnt%hello%3.pdf
14/12/2014  00:28                 0 co,mm,a1.pdf
14/12/2014  00:28                 0 co,mm,a2.pdf
14/12/2014  00:28                 0 co,mm,a3.pdf
14/12/2014  00:28                 0 se;mi1.pdf
14/12/2014  00:28                 0 se;mi2.pdf
14/12/2014  00:28                 0 se;mi3.pdf
14/12/2014  00:28             1,074 newfile.txt
              32 File(s)          1,074 bytes
               2 Dir(s)   2,099,904,512 bytes free

然后这批:

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
PUSHD "%sourcedir%"
(
FOR /f "delims=" %%a IN (
 'dir /b /a-d *.pdf *.xls'
 ) DO (
SET "oname=%%a"
CALL :alter
)
)>newfile.txt
popd
GOTO :EOF

:alter
SET "name=%oname:&=and%"
SET "name=%name:#=%"
SET "name=%name: LTD=%"
ECHO(REN "%oname%" "%name%"
GOTO :eof

收益率,u:\sourcedir\t w o\newfile.txt

REN "amper&1.pdf" "amperand1.pdf"
REN "amper&2.pdf" "amperand2.pdf"
REN "amper&3.pdf" "amperand3.pdf"
REN "LTD LTD 1.pdf" "LTD 1.pdf"
REN "LTD LTD 2.pdf" "LTD 2.pdf"
REN "LTD LTD 3.pdf" "LTD 3.pdf"
REN "lower ltd 1.pdf" "lower 1.pdf"
REN "lower ltd 2.pdf" "lower 2.pdf"
REN "lower ltd 3.pdf" "lower 3.pdf"
REN "ALL#& LTD 1.pdf" "ALLand 1.pdf"
REN "ALL#& LTD 2.pdf" "ALLand 2.pdf"
REN "ALL#& LTD 3.pdf" "ALLand 3.pdf"
REN "shriek!hello!1.pdf" "shriek!hello!1.pdf"
REN "shriek!hello!2.pdf" "shriek!hello!2.pdf"
REN "shriek!hello!3.pdf" "shriek!hello!3.pdf"
REN "pcnt%hello%1.pdf" "pcnt%hello%1.pdf"
REN "pcnt%hello%2.pdf" "pcnt%hello%2.pdf"
REN "pcnt%hello%3.pdf" "pcnt%hello%3.pdf"
REN "co,mm,a1.pdf" "co,mm,a1.pdf"
REN "co,mm,a2.pdf" "co,mm,a2.pdf"
REN "co,mm,a3.pdf" "co,mm,a3.pdf"
REN "se;mi1.pdf" "se;mi1.pdf"
REN "se;mi2.pdf" "se;mi2.pdf"
REN "se;mi3.pdf" "se;mi3.pdf"
REN "file1.xls" "file1.xls"
REN "file2.xls" "file2.xls"
REN "file3.xls" "file3.xls"
REN "hash#1.xls" "hash1.xls"
REN "hash#2.xls" "hash2.xls"
REN "hash#3.xls" "hash3.xls"