如何通过目录中多个文件上的字符串替换文件名中的第一个空格?

时间:2018-03-29 06:18:19

标签: batch-file batch-rename

有没有人知道如何在文件名的前8个字符后用文件_TEMP-替换文件名中的第一个空格?

此外,我希望编写一个可以更改具有相似文件名结构的目录中的多个文件的批处理文件。

例如:

之前: 12345678 Hello World.txt

之后: 12345678_TEMP-Hello World.txt

2 个答案:

答案 0 :(得分:1)

以下是一个简单的代码,演示了 FOR 在此任务中的用法:

@echo off
set "FileName=12345678 Hello World.txt"
for /F "tokens=1*" %%I in ("%FileName%") do echo ren "%FileName%" "%%I_TEMP-%%J"
set "FileName="
echo/
pause

此处将文件名分配给环境变量。

使用选项/F FOR 命令将使用双引号指定的文件名字符串拆分为使用默认分隔符空格和水平制表符的子字符串。

定义tokens=1*时,第一个空格/制表符分隔字符串被分配给指定的循环变量I。星号负责在第一个字符串之后不进一步拆分空格/制表符,而是在第一个字符串之后的空格/制表符之后将所有内容分配给根据ASCII table循环变量的下一个循环变量{ {1}}。因此,对于此示例,J被分配I12345678被分配J

要执行的命令是 ECHO ,它会打印命令行以重命名将在没有Hello World.txt的情况下执行的文件。

另一个批处理代码,它重命名当前目录中的所有非隐藏文件,文件名中的空格不包含文件名中的echo

_TEMP-

外部 FOR 在一个单独的命令进程中执行,该进程以后面的命令行@echo off for /F "eol=| delims=" %%# in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /V /C:_TEMP- 2^>nul') do ( for /F "tokens=1*" %%I in ("%%#") do ren "%%#" "%%I_TEMP-%%J" ) 开始:

cmd.exe /C

DIR 在当前目录中搜索,因为dir "* *" /A-D-H /B 2>nul | C:\Windows\System32\findstr.exe /L /V /C:_TEMP- 2>nul (属性不是目录而非隐藏)仅针对与通配符模式/A-D-H匹配的非隐藏文件,并仅输出找到的文件由于* *(裸格式)而导致的名称。通过将写入处理 STDERR 的错误消息重定向到设备 NUL ,可以抑制没有符合这些条件的文件的错误消息。

DIR 输出的用于处理 STDOUT 的文件名被重定向到命令 FINDSTR STDIN 文件名列表区分大小写,字面意思是字符串/B。但输出不是包含此字符串的行,而是由_TEMP-引起的反转结果。因此输出是 FINDSTR 来处理 STDOUT 包含字符串/V的所有行 FINDSTR 输出的 STDERR 输出的错误消息可通过将其重定向到设备 NUL 来抑制。

外部 FOR 将输出捕获到后台命令进程的 STDOUT ,然后逐行处理捕获的输出。这里处理捕获的文件名列表非常重要,因为要在 FOR 循环内的命令重命名当前目录中要修改的文件。否则,在使用 FOR 本身查找与通配符模式_TEMP-匹配的文件时,可能会发生重命名的文件被多次处理或者由于当前目录中的文件列表在循环期间发生更改而跳过某些文件执行。

FOR 始终忽略空行,但文件名列表不包含空行。

* *也会忽略默认以分号开头的行。通过指定for /F来跳过以竖线开头的行来更改此行为。文件名可以以分号开头,但文件名不能包含竖线。因此,请确保不使用eol=|跳过任何文件名。

带有默认选项的

eol=|会在空格/制表符上拆分一行(文件名),并将第一个子串分配给指定的循环变量for /F。此行为不太好,因为文件重命名任务需要来自 DIR 的过滤输出的完整文件名。因此#用于指定一个空的分隔符列表,导致不将行(文件名)拆分为子串(标记)。

可能是文件名为delims=,文件名中有多个空格。这是首先将循环变量12345678 Hello World.txt分配给当前目录中 DIR 找到的完整文件名的原因。

如上所述,文件名被分成两个子字符串,如果当前目录中还没有新名称的文件或文件夹,并且当前共享的应用程序未打开要重命名的文件,则将其重命名为成功访问被拒绝。

上面的批处理文件也可以使用批处理文件中的单个命令行进行编码:

#

或者单个命令行实际上是直接在命令提示符窗口中执行,如下所示,只有一个百分号符号引用循环变量@for /F "eol=| tokens=1*" %%I in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /V /C:_TEMP- 2^>nul') do @ren "%%I %%J" "%%I_TEMP-%%J" I

J

但是这个单一命令行版本仅适用于在文件名的第一部分和剩余部分之间始终具有单个空格字符的文件,即它适用于for /F "eol=| tokens=1*" %I in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /V /C:_TEMP- 2^>nul') do @ren "%I %J" "%I_TEMP-%J" 但不适用于12345678 Hello World.txt。< / p>

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

  • 12345678 Hello World.txt
  • dir /?
  • echo /?
  • findstr /?
  • for /?
  • pause /?
  • ren /?

另请阅读Microsoft有关Using Command Redirection Operators的文章,了解set /?2>nul的说明。必须使用 FOR 命令行上的插入符|对重定向运算符>|进行转义,以便在Windows命令解释程序处理此命令行时将其解释为文字字符在执行命令 FOR 之前,它在后台启动的单独命令进程中执行嵌入式命令行。

答案 1 :(得分:0)

这是一个可能的批处理文件解决方案,用于使用给定的字符串_TEMP-替换第9个字符; 它使用PowerShell

@Echo Off
Set "SD=%UserProfile%\Documents"
PowerShell -C "GI '%SD%\???????? *.txt'|Ren -N {$_.BaseName.Remove(8,1).Insert(8,'_TEMP-')+$_.Extension} -Wh"
Pause

只需将第%UserProfile%\Documents行上的2更改为包含.txt个文件的文件夹(如果它们不是真正.txt个文件,请更改{{ 1}}在txt行到相应的字符串或通配符。如果您要添加的字符串也不同,请将第3_TEMP-替换为您想要的字符串)。该脚本目前旨在向您展示要重命名的文件会发生什么;如果您对输出感到满意,请更改脚本:

3

如果您不想在@Echo Off Set "SD=%UserProfile%\Documents" PowerShell -C "GI '%SD%\???????? *.txt'|Ren -N {$_.BaseName.Remove(8,1).Insert(8,'_TEMP-')+$_.Extension}" 个字符后删除空格,那么:

8

...同样如果您对输出感到满意,请将脚本更改为:

@Echo Off
Set "SD=%UserProfile%\Documents"
PowerShell -C "GI '%SD%\???????? *.txt'|Ren -N {$_.BaseName.Insert(8,'_TEMP-')+$_.Extension} -Wh"
Pause

我确信即使使用PowerShell,也会有更好的方法,但鉴于您提供的信息不足,我现在无法提出任何建议。