windows 如何递归地从文件中删除后缀?

xdnvmnnf  于 2023-08-07  发布在  Windows
关注(0)|答案(1)|浏览(127)

我有一个目录,其中有其他目录,其中有一个类似的文件结束:“* test today.cpp”。我想去掉“今天考试”这部分。怎么办呢?我在互联网上搜索,但没有一个解决方案。
我尝试了以下解决方案:

powershell -C "gci | % {rni $_.Name ($_.Name -replace ' test today', '')}"

x

setlocal enableDelayedExpansion
for /r %%F in ("* test today.cpp") do (
  set "name=%%F"
  ren "!name!" "!name: test today=!"
)
ren "* test today.cpp" "*.cpp"
FOR /R %x IN (* test today.cpp) DO ren "%x" "*.cpp"

的数据

2exbekwf

2exbekwf1#

可以使用下面的批处理文件,在当前工作目录中递归搜索匹配通配符模式* test today.cpp的文件,并通过删除test today部分来重命名这些文件。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /R %%I in ("* test today.cpp") do (
    set "FullName=%%I"
    set "FileName=%%~nxI"
    setlocal EnableDelayedExpansion
    ren "!FullName!" "!FileName: test today=!"
    endlocal
)
endlocal

字符串
此批处理文件的作品,即使任何完全合格的文件名(驱动器+路径+名称+扩展名)包含一个或多个感叹号,因为delayed variable expansion只是启用了做文件重命名。有关SETLOCALENDLOCAL命令的详细信息,请参阅this answer
更快的解决方案是:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /R %%I in ("* test today.cpp") do (
    set "FullName=%%I"
    set "FileName=%%~nxI"
    ren "!FullName!" "!FileName: test today=!"
)
endlocal


但是,如果分配给循环变量I的完整路径文件名包含一个或多个!,则此解决方案不起作用,因为感叹号现在被解释为两个命令行上的延迟扩展变量引用的开始/结束set
在问题中发布的类似代码在启用延迟变量扩展时不起作用,因为命令REN需要没有路径的新名称,而问题中发布的代码并非如此。

注1:当前工作目录可以是任意目录。它不能是包含批处理文件的目录。以%SystemRoot%\System32\cmd.exe为应用程序,通过调用Windows内核库函数CreateProcess启动cmd.exe的过程定义了当前工作目录**。可以使用for /R "%~dp0" %%I在批处理文件目录而不是当前工作目录中进行递归搜索。
注2:*FOR忽略设置了隐藏属性的文件。
**注3:**上述两个批处理文件在NTFS驱动器上工作,但在以FAT32或exFAT作为文件系统的驱动器上不工作。下面的两个批处理文件适用于任何文件系统。

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "delims=" %%I in ('dir "* test today.cpp" /A-D /B /S 2^>nul') do (
    set "FullName=%%I"
    set "FileName=%%~nxI"
    setlocal EnableDelayedExpansion
    ren "!FullName!" "!FileName: test today=!"
    endlocal
)
endlocal


由于永久启用了延迟变量扩展,因此解决方案更快:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "delims=" %%I in ('dir "* test today.cpp" /A-D /B /S 2^>nul') do (
    set "FullName=%%I"
    set "FileName=%%~nxI"
    ren "!FullName!" "!FileName: test today=!"
)
endlocal


具有隐藏属性的文件也被这两个批处理文件重命名,除了/A-D被修改为/A-D-H以忽略具有隐藏属性的文件。
可以在*的左边插入%~dp0,让DIR在批处理文件目录中递归搜索,而不是在当前工作目录中搜索要重命名的文件。%~dp0扩展到参数0的驱动器和路径,这是完整的批处理文件目录路径,始终以反斜杠结尾,并与*连接,因此没有额外的反斜杠。
在批处理文件目录中递归重命名文件的示例,独立于文件系统,独立于完全限定文件名中的一个或多个!

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "delims=" %%I in ('dir "%~dp0* test today.cpp" /A-D /B /S 2^>nul') do (
    set "FullName=%%I"
    set "FileName=%%~nxI"
    ren "!FullName!" "!FileName: test today=!"
)
endlocal


要了解所使用的命令及其工作方式,请打开command prompt窗口,在那里执行以下命令,并完整仔细地阅读每个命令的帮助页面。

  • call /? ...解释%~dp0
  • dir /?
  • echo /?
  • endlocal /?
  • ren /?
  • set /?
  • setlocal /?

阅读有关Using command redirection operators的Microsoft文档,了解2>nul的说明。在执行FOR命令之前,Windows命令解释器处理FOR命令行时,必须使用插入符号^对重定向运算符>进行转义,以将其解释为文字字符它使用一个单独的命令进程执行嵌入的dir命令行,该命令进程在后台使用%ComSpec% /c和内部的命令行启动'作为附加参数追加。

相关问题