由于文件路径中的空格,批处理脚本无法正常工作

Batch script not working due to spaces in file paths

所以我对批处理脚本和一般脚本不熟悉。我最近制作了一个脚本,其中源目录中的文件将根据其 'last modified date' 组织到目标目录中。

这是脚本的摘录:

@echo off
Setlocal EnableDelayedExpansion
echo Organise files
set /P _a="Enter source directory:"
set /P _b="Enter destination directory:"
set /P _c="Organise files by dd-mm-yyyy format (last modified)? y or n?" 
if %_c% == y goto:ddmmyy

:ddmmyy
for %%A in ("%_a%\*") do echo %%~tA %%~snA %%~xA >> "%_a%\testtoken.txt"
for /F "tokens=1-7* delims=./ " %%B in (%_a%\testtoken.txt) do (
robocopy "%_a%" "%_b%\%%B-%%C-%%D" "%%G.%%H" /xf testtoken.txt /mov
)

除非我使用名称中带有空格的目录(例如 C:\Program Files 而不是 C:\Program),否则脚本工作正常。在我使用 8.3 表示法之前,我在文件名中也遇到了同样的空格问题,但是使用 8.3 表示法会导致其他问题,例如 robocopy 不会复制名称非常相似的文件(例如 TUTORI~2、TUTORI~1、TUTORI~3 等。 )

testtoken.txt的格式如下:

02/11/2014 06:02 PM SPSETU~1 .exe 
16/11/2014 09:19 AM TUTORI~4 .docx 
14/11/2014 12:00 PM TUTORI~2 .docx 
16/11/2014 09:19 AM TUTORI~3 .docx 
14/11/2014 12:00 PM TUTORI~1 .docx 
16/11/2014 09:19 AM TU44E0~1 .docx 
16/11/2014 09:19 AM TU05DE~1 .docx 
16/11/2014 10:59 PM UNIFYI~1 .pdf 
09/11/2014 07:55 PM ZOROAS~1 .jpg 

那么有没有办法让脚本忽略空格?为什么 robocopy 不会以 8.3 表示法复制名称非常相似的文件,有什么方法可以强制 robocopy 实际复制文件?

您可能应该稍微更改一下文件的格式。不要将扩展名放在最后一列,而只需在那里使用文件名。然后您知道最后一个标记延伸到该行的其余部分,包括任何空格:

for /f "tokens=1-5* delims=/ " %A in ("09/11/2014 07:55 PM Test file with spaces.jpg") do (echo %F)

至于引用任何带空格的路径,我现在没有发现任何明显的问题。 for ... in (%_a%\testtoken.txt) 可能是个问题,可以用

解决
for /f "usebackq <other options>" ... in ("%_a%\testtoken.txt") do ...

至少在文档可信的情况下:

usebackq        - specifies that the new semantics are in force,
                  where a back quoted string is executed as a
                  command and a single quoted string is a
                  literal string command and allows the use of
                  double quotes to quote file names in
                  file-set.
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
for %%A in ("%sourcedir%\*") do echo %%~tA %%~fA>> "%sourcedir%\testtoken.txt"
for /F "USEBACKQ tokens=1,2,3,5* delims=/ " %%B in ("%sourcedir%\testtoken.txt") do IF /i "%%~nxF" neq "testtoken.txt" (

 REM method 1 - robocopy
 echo(robocopy "%%~dpF." "%destdir%\%%D-%%C-%%B" "%%F" /mov

 REM method 2 - XCOPY
 ECHO(XCOPY "%%F" "%destdir%\%%D-%%C-%%B\"

 REM method 3 - MD and move
 ECHO(MD "%destdir%\%%D-%%C-%%B\"
 ECHO(MOVE "%%F" "%destdir%\%%D-%%C-%%B\"

 ECHO ==================================
)

GOTO :EOF

您需要更改 sourcedirdestdir 的设置以适合您的情况。我已将变量名称更改为更具描述性的名称。

注意:我已将日期反转为 yyyy-mm-dd 格式,这种格式比 dd-mm-yyyy 格式更容易排序。如果您坚持 dd-mm-yyyy,只需反转令牌顺序 %%D-%%C-%%B。

我更喜欢方法 2 或 3 而不是 robocopy,所以我不是特别熟悉 robocopy 语法。 YMMV.

所需的 MD 命令仅 ECHOed 用于测试目的。 确认命令正确后,将ECHO(MD 更改为MD 以实际创建目录。附加 2>nul 以抑制错误消息(例如,当目录已经存在时)

所需的 MOVE 命令仅 ECHOed 用于测试目的。 确认命令正确后,将ECHO(MOVE 更改为MOVE 以实际移动文件。附加 >nul 以禁止报告消息(例如 1 file moved

所需的 XCOPY 命令仅 ECHO 用于测试目的。 确认命令正确后,将ECHO(XCOPY更改为XCOPY以实际复制文件。

所需的 ROBOCOPY 命令仅 ECHO 用于测试目的。 确认命令正确后,将ECHO(ROBOCOPY更改为ROBOCOPY以实际复制文件。

显然,三种方法中选择一种。

请注意,排除 testtoken.txt 可能无效,因为您的代码针对的是短文件名,而 testtoken.txt 是长文件名。我不确定 robocopy 是否会例外,但我实现的 if 门肯定会。

由于我的日期格式和你的不同,我用你的数据在我的系统上测试了程序。显然,它似乎有效,否则我不会费心发布它。

for...%%B 语句中的令牌控件重新设计为将日、月和年分配给 %%B、C、D,跳过令牌 4(时间)并分配 %%E "AM/PM) - 用作虚拟。%%F 获取该行的其余部分,这应该是 %%~fA 生成的完整文件名到列表文件中。


编辑代码以删除终端 space 并添加到 testtoken.txt 行以响应 OP 评论。