如何忽略批处理 FOR 循环中使用的变量中的空格

How to ignore spaces in variable used in a batch FOR loop

我 运行 google 我的 children 侦察兵 BSA 部队的驱动器帐户,因此从所有其他 parents 获得成百上千张图片每个事件。我创建了一个简单的小批量,允许我将我获得的所有图片放在一个目录中并将它们重命名为“Some_Event-1.png、Some_Event-2.png”等。大多数情况下这很好用。但是一些提供的文件名中有 space,这似乎导致 运行 批处理时出现“找不到文件”问题。无论文件名是否具有 space,如何让我的 FOR 循环中的重命名命令起作用?我在下面使用的代码:

(注意:我将标志传递给批处理,而不是在批处理中使用用户输入。格式为“BATREN.BAT N EXT New_name”,其中N/%1 是希望它开始编号的数字,EXT/%2 是我想要定位的扩展名,例如 jpg 或 png,New_name/%3 是要分配的新名称。)

@ECHO OFF
setlocal enabledelayedexpansion

DIR *.%2 /B>C:\Users\MyUser\AppData\Local\Temp\FileList.txt
Set /A CNT=%1

FOR /F %%i IN (C:\Users\MyUser\AppData\Local\Temp\FileList.txt) DO (
    REN %%i %3-!CNT!.%2
    SET /A CNT+=1
)
EXIT /B

我试图找到与我在这里提出的问题类似的答案,但似乎没有答案,要么我是盲人要么是白痴,如果已经有的话,所以我为此深表歉意。

你的麻烦来自引号和定界符。

  • FOR 命令指定 delims
  • 如果您必须提供“spaced”文件名目标,可以选择在 REN 命令的右侧部分添加引号。

编辑: 感谢@compo,删除了 usebackq 因为它是用于命令而不是输出...我老了...

@ECHO OFF
setlocal enabledelayedexpansion

DIR *.%2 /B>C:\Users\MyUser\AppData\Local\Temp\FileList.txt
Set /A CNT=%1

FOR /F "delims=" %%i IN (C:\Users\MyUser\AppData\Local\Temp\FileList.txt) DO (
    REN "%%i" "%3-!CNT!.%2"
    SET /A CNT+=1
)
EXIT /B

说明:delims= 选项告诉 FOR 命令获取每个字符,直到遇到换行符。默认情况下,FOR命令的分隔符是一个空白space,这就是为什么当它们有一个空白时你只能得到部分文件名。

这是我如何完成任务的简单示例,无需创建中间文本文件:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "Count=%~1"
For /F Delims^=^ EOL^= %%G In ('Dir "*.%~2" /B /A:-D 2^>NUL') Do (
    SetLocal EnableDelayedExpansion
    Ren "%%G" "%~3-!Count!%%~xG"
    EndLocal
    Set /A Count += 1
)

该示例不验证是否收到任何参数,或者收到的参数是否正确。即第一个是整数,第二个是不包含句点的字符串,第三个是不包含 Windows 文件名中无效字符的字符串。我建议任何可靠的解决方案都应该执行该验证,这超出了您的问题范围。此外,没有检查任何预期的文件名是否已经存在,虽然它可能不太可能存在,但一个强大的解决方案可能应该包括用于确定在这种情况下会发生什么的代码。

然而,示例确实如此,根据我的评论,确保没有分隔符,(delims),并对文件名字符串加双引号,以保护空格和其他有问题的字符。此外,它没有定义 eof(行首) 字符,因为默认值为 ;,这是文件名开头的有效字符.

您还应该知道,在启用了 8.3 命名的系统上,(默认),文件 glob 示例:*.jpe 不列出文件不区分大小写的扩展名 .jpe,它列出了所有名称以句点结尾、后跟字符串 jpe 和零个或多个非句点字符(也包括 .jpeg)的项目。 *.tif 也是如此,它也会 return .tiff 个文件。现在这可能不是问题,实际上可能是一个好处,但如果它可能是一个不需要的问题,您应该包含一个过滤器以确保只处理与您的输入匹配的扩展名,(再一次这个不在你的问题范围内).


如果你只是想看看会发生什么,而不实际执行重命名操作,你可以将代码更改为这样,修改后的代码只是为了让任何输出都不会遗漏可能的 ! 个字符枚举的文件名,(由于延迟扩展):

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "Count=%~1"
For /F Delims^=^ EOL^= %%G In ('Dir "*.%~2" /B /A:-D 2^>NUL') Do (
    Set "FileName=%%G"
    SetLocal EnableDelayedExpansion
    Echo Ren "!FileName!" "%~3-!Count!%%~xG"
    EndLocal
    Set /A Count += 1
)

您当然也可以将其用于实际的重命名任务,只需从行 7.

中删除 Echo