从文件名中删除特殊字符的脚本

4

我有一个包含大量文件的文件夹。很多文件名中都包含“%”和/或“&”字符。

e.g. Test&doc.pdf
e.g Test%doc.doc

有没有一种快速的方法能够通过windows批处理文件、vbscript或类似的方式删除“%”和“&”字符?
非常感谢您的帮助。
谢谢。

该文件夹位于我无法访问的远程服务器上。因此,我想给有访问权限的人一个可以运行一次的脚本。 - Riain McAtamney
我猜它不一定要是批处理文件。它可以是VBScript或类似的东西。我会更新问题。 - Riain McAtamney
3个回答

3

以下是批处理的执行方法(如果您感兴趣)。 但是,如果您的文件名中包含多个百分号,则无法使用此方法,因为shell将其扩展为变量。 我不知道如何立即解决这个问题。

它从脚本所在的任何目录开始,并递归地遍历所有子目录。

@echo off

setlocal enabledelayedexpansion
for /f "usebackq delims=" %%N in (`dir /s /b`) do (
  set var=%%~nN
  set var=!var:^&= !
  set var=!var:%%= !

  if not "!var!"=="%%~nN" (
    if not exist "%%~dpN!var!%%~xN" (
      echo "%%N" --^> "!var!%%~xN"
      ren "%%N" "!var!%%~xN"
    ) else (
      echo File "!var!%%~xN" ^(from %%N^) already exists.
    )
  )
)

例如,输出结果如下:
C:\batch\schar>schar
"C:\batch\schar\Test%doc.doc" --> "Test doc.doc"
"C:\batch\schar\Test%doc.pdf" --> "Test doc.pdf"
File "Test doc.pdf" (from C:\batch\schar\Test&doc.pdf) already exists.
"C:\batch\schar\subdir\FILE%here" --> "FILE here"

我已经测试过了,它可以处理多个百分号,但无法处理感叹号和插入符号。 - jeb
@jeb:谢谢你的查看。我越看越意识到这是一个极其困难的问题。我就是想不出如何阻止 shell 在字符串中评估特殊字符。这个答案有很多限制,我可能应该把它删除。如果有人能够提供一个没有字符限制的批处理解决方案,我会非常印象深刻。 - indiv
我希望我的解决方案可以处理所有字符,没有任何限制。 - jeb

3

@indiv

如果有人能够提供一个没有字符限制的批处理解决方案,我会非常惊讶。

好的,我会尝试。

@echo off

setlocal DisableDelayedExpansion
for /f "usebackq delims=" %%N in (`dir /s /b`) do (
  set var=%%~nxN
  setlocal EnableDelayedExpansion
  set "org=!var!"
  set "var=!var:&= !"
  set "var=!var:%%= !"

  if not "!var!"=="!org!" (
    if not exist "%%~dpN!var!" (
      echo "!org!" --^> "!var!"
      ren "!org!" "!var!"
    ) else (
      echo File "!var!" ^(from !org!^) already exists.
    )
  )
  endlocal
)

关键是要切换延迟扩展,因为for循环变量(%%N)的扩展应该在没有延迟扩展的情况下完成,否则您会丢失感叹号,并且会遇到插入符的问题。 但是,为了处理和修改字符串,您应该使用延迟扩展。
为什么呢?答案是要理解批处理解析器的阶段。
我在这里尝试解释一下。 how-does-the-windows-command-interpreter-cmd-exe-parse-scripts

干得好,比我的解决方案更好。它在Test^!doc.xls中存在问题,其中将插入符号解释为!的转义字符。当应该有2个空格时,它会产生替换Test doc.xls。对于像F%ILE%he%re这样的文件名,ren命令也存在问题。替换有效,生成F ILE he re,但重命名不起作用,因为ren的第一个参数具有未转义的。我认为在批处理中转义特殊字符或抑制其评估(如perl中的')并没有简单的解决方案。 - indiv
重命名F%ILE%he%re是可行的,因为使用ren“!org!”进行扩展是安全的,因为延迟扩展后不再进行解析。在我的批处理中,“f%test^!doc.xls”也成功地重命名为“f test^!doc.xls”。 - jeb

2

我匆忙地拼凑了这个代码,没有测试过,但这段VBScript应该能解决问题。如果需要像文件夹递归替换等高级功能,请告诉我。

Set objFSO = CreateObject("Scripting.FileSystemObject")

'Your folder here
objStartFolder = "X:\MYFOLDER"

Set objFolder = objFSO.GetFolder(objStartFolder)
Set regEx = New RegExp

'Your pattern here
regEx.Pattern = "[&%]" 

Set colFiles = objFolder.Files
For Each objFile in colFiles
    objFile.Rename(regEx.Replace(objFile.Name, "")
Next

我正要上传我的答案,它的工作方式与你的相同。谢谢你的帮助! - Riain McAtamney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接