【问题标题】:Batch script not working due to spaces in file paths由于文件路径中的空格,批处理脚本无法正常工作
【发布时间】:2015-04-03 16:12:23
【问题描述】:

所以我是批处理脚本和一般脚本的新手。我最近制作了一个脚本,其中源目录中的文件将根据其“上次修改日期”组织到目标目录中。

这是脚本的摘录:

@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 实际复制文件?

【问题讨论】:

  • PowerShell 是从哪里来的?我只看到一个批处理文件。
  • 我只是为了可见性而添加的,因为 afaik powershell 类似于批处理。不过,我现在将其删除
  • 这是一种完全不同的语言,目的略有重叠;)

标签: batch-file scripting cmd batch-processing


【解决方案1】:
@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 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(XCOPY更改为XCOPY以实际复制文件。

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

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

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

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

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


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

【讨论】:

  • robocopy 方法不起作用。我查看了 robocopy 日志,发现不是将 robocopy 命令调用为:robocopy "source" "destination" "file to be copied.extension",而是在“filename.extension”之后添加了一个额外的空格,例如:robocopy "source" "destination" "file to be copied.extension ",robocopy 无法识别
【解决方案2】:

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

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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 2013-03-06
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多