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

For loop 如何忽略批处理FOR循环中使用的变量中的空格,for-loop,batch-file,whitespace,For Loop,Batch File,Whitespace,我为我的孩子童子军BSA团队运行google drive帐户,因此每次活动都会从其他家长那里收到成百上千张照片。我创建了一个简单的小批量,允许我将所有图片放在一个目录中,并将它们重命名为“Some_Event-1.png,Some_Event-2.png”等。在大多数情况下,这非常有效。但是,有些文件名中有空格,这似乎会在运行批处理时导致“找不到文件”问题。无论文件名是否有空格,如何使FOR循环中的rename命令起作用?我在下面使用的代码: (注意:我将标志传递给批处理,而不是在批处理中使用用

我为我的孩子童子军BSA团队运行google drive帐户,因此每次活动都会从其他家长那里收到成百上千张照片。我创建了一个简单的小批量,允许我将所有图片放在一个目录中,并将它们重命名为“Some_Event-1.png,Some_Event-2.png”等。在大多数情况下,这非常有效。但是,有些文件名中有空格,这似乎会在运行批处理时导致“找不到文件”问题。无论文件名是否有空格,如何使FOR循环中的rename命令起作用?我在下面使用的代码:

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


我试图找到一个与我在这里所问问题相似的答案,但似乎没有,要么我是盲人,要么我是白痴(如果有的话),所以我对此表示歉意。

你的麻烦来自引用和分隔符

  • for
    命令指定
    delims
  • (可选)在命令的右侧部分添加引号,以防您必须提供“间隔”的文件名目标
编辑:感谢@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
命令的分隔符是一个空格,这就是为什么当文件名为空时,只能得到部分文件名的原因。

下面是一个快速示例,说明我如何处理任务,而无需创建中间文本文件:

@Echo关闭
SetLocal EnableExtensions DisableDelayedExpansion
设置“计数=%~1”
对于/F Delims^=^EOL^=%%G In('Dir“*。%%~2”/B/A:-d2^>NUL)Do(
SetLocal EnableDelayedExpansion
任“%%G”“%~3-!计数!%%~xG”
端部
设置/A计数+=1
)
该示例不验证是否接收到任何参数,也不验证接收到的参数是否正确。i、 e.第一个是整数,第二个是不包含句点的字符串,第三个是不包含Windows文件名中任何无效字符的字符串。我建议任何健壮的解决方案都应该执行该验证,这超出了您的问题范围。此外,没有检查任何预期的文件名是否已经存在,虽然可能不太可能,但一个健壮的解决方案可能应该包括用于确定在这种情况下会发生什么的代码

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

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


如果您只是想看看会发生什么,而不实际执行重命名操作,您可以将代码更改为此,此代码已被修改,以便任何输出都不会忽略可能的
枚举文件名中的字符(由于扩展延迟):

@Echo关闭
SetLocal EnableExtensions DisableDelayedExpansion
设置“计数=%~1”
对于/F Delims^=^EOL^=%%G In('Dir“*。%%~2”/B/A:-d2^>NUL)Do(
设置“文件名=%%G”
SetLocal EnableDelayedExpansion
Echo Ren“!FileName!”“%~3-!Count!%%~xG”
端部
设置/A计数+=1
)

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

即可打开命令提示窗口,键入
以获取/?
,按
[ENTER]
键,然后阅读使用信息,特别注意
for/F
语法。您需要使用
“delims=“
”或
“tokens=*”
,以防止默认的空格或表格分隔您的输出。然后,您需要在
REN
命令中双重引用文件名sting,例如
REN“P:\ath\to\file.ext”“newname.ext”
@Compo这一个似乎是部分重复,但最后一个问题是“我的问题是,如何将带有空格的名称分配给变量?”,因此可能不是明确的重复。这也可以匹配,但与引用输出有关。找到dup:,很抱歉打扰您。这是否回答了您的问题?谢谢我一定要去看看。我确实在那里有论证验证,还有评论和手册页,因为这就是我被教导这样做的方式,但是为了在这里发布的目的,我认为没有必要包括一段IFs和几个不相关的批次标签。我不相信以下任何一条都是正确的,“使用
usebackq
选项告诉
FOR
命令引用其输出,这样您就不必引用<
@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