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

问题描述 投票:0回答:1

我有一个目录,其中还有其他目录,其中有类似结尾的文件:“* test Today.cpp”。我想删除“今天测试”部分。怎么做?我在互联网上搜索过,但没有一个解决方案适合。

我尝试了以下解决方案:

powershell -C "gci | % {rni $_.Name ($_.Name -replace ' test today', '')}"
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"
windows cmd file-rename
1个回答
1
投票

可以使用以下批处理文件在当前工作目录中递归搜索与通配符模式

* 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

即使任何完全限定的文件名(驱动器+路径+名称+扩展名)包含一个或多个感叹号,该批处理文件也可以工作,因为在进行文件重命名时刚刚启用了延迟变量扩展。请阅读此答案,了解有关命令 SETLOCALENDLOCAL 的详细信息。

更快的解决方案是:

@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: 当前工作目录可以是任何目录。它不能是包含批处理文件的目录。通过调用 Windows 内核库函数

CreateProcess
并将 cmd.exe 作为要运行的应用程序来启动
%SystemRoot%\System32\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

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

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

阅读有关 使用命令重定向运算符的 Microsoft 文档,了解

2>nul
的说明。重定向运算符
>
必须在
FOR
命令行上使用脱字符号 ^ 进行转义,以便在 Windows 命令解释器在执行命令 FOR(执行嵌入的
dir
命令行)之前处理此命令行时将其解释为文字字符使用在后台启动的单独命令进程,并使用
%ComSpec% /c
'
内的命令行作为附加参数附加。

© www.soinside.com 2019 - 2024. All rights reserved.