【问题标题】:Passing messy file variables to robocopy将杂乱的文件变量传递给 robocopy
【发布时间】:2022-01-16 20:55:02
【问题描述】:

我正在尝试将一组变量传递给robocopy,所有变量都包含空格并且可能很长。我需要能够以使robocopy 捕获完整路径的方式包装参数。

:: Define array of input files to copy
set "MASTER_SOURCE=\\path\with\some file\and messy. folder name\bla bla --- bla\stuff"
set "SOURCE_FILES[0]=%MASTER_SOURCE%\this file with a pesky name.csv"
set "SOURCE_FILES[1]=%MASTER_SOURCE%\this other file with a pesky name.csv"

:: Define output file path
SET "OUTPUT_ROOT=C:\Users\me\stuff and things\save here"

:: Create dated folder within the OUTPUT_ROOT location
:: Obtain date/time timestamps
:: Source: https://stackoverflow.com/a/19706067/1655567
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"

:: Define output path
set "OUTPUT_DIR=%OUTPUT_ROOT%\%fullstamp%"
:: Create output path
mkdir "%OUTPUT_DIR%"
echo.
echo Progressing messy file copying
echo Created output: %OUTPUT_DIR%.

:: Define robocopy log file
set "ROBO_LOG=%OUTPUT_DIR%\robocopy.log"

:: Iterate over array elements and copy files
:: Set counter
set "x=0"

:SymLoop
if defined SOURCE_FILES[%x%] (
    call set "FILE_FULL_PATH=%%SOURCE_FILES[%x%]%%"
    echo Copying: %FILE_FULL_PATH%
    for /F "delims=" %%I IN ("%FILE_FULL_PATH%") do (
        call set "FILE_NAME=%%~nxI"
        echo File name: %FILE_NAME%
        call set "FILE_PATH=%%~dpI"
        echo File path: %FILE_PATH%
    ) 
    robocopy \"%FILE_PATH%\" \"%OUTPUT_DIR%" "%FILE_NAME%" /R:5 /W:2 /V /LOG+:"%ROBO_LOG%"
    call echo Finished copying: %FILE_NAME%
    set /a "x+=1"
    GOTO :SymLoop

)

问题

问题在于行:

robocopy \"%FILE_PATH%\" \"%OUTPUT_DIR%" "%FILE_NAME%" /R:5 /W:2 /V /LOG+:"%ROBO_LOG%"

错误

返回的错误是:

错误:参数 #3 无效:“Data\”C:\Users\me\stuff and things\

我尝试查看其他答案1、2 并修改传递给 robocopy 的内容,在 " 之前和之后添加 \,但我无法找到/图解决方案,使我能够正确传递以下内容:

  • FILE_PATH - 文件所在文件夹的路径,包含空格和其他不需要的字符
  • OUTPUT_DIR - 文件复制到的目录路径,包括空格和其他不需要的字符
  • FILE_NAME - 要复制的文件名

其他要点

  • 我需要SOURCE_FILES 作为一个数组,因为我必须遍历文件路径以找到位于多个 LAN 共享等中的源单个文件,所以我不能只使用 *.csv 之类的东西传递文件夹的路径。我们的想法是将SOURCE_FILES 扩展到多个项目。

1this discussion, 中表达了有关手动路径编辑的建议。这没有帮助,因为我打算传递一些名称可能很困难的文件。

2here 表达了类似的建议。

【问题讨论】:

  • 您的源目录或目标目录不能有尾部反斜杠。您还应该了解整个路径应该用双引号括起来,而不仅仅是它们的个别部分,即不正确:C:\"Program Files"\"Internet Explorer",正确:"C:\Program Files\Internat Explorer"\ 也是一个位置,它表示当前目录的根目录,所以如果您当前的工作目录是D:\MyPath\MyCurrentDirectory\ 将表示D:\。因此,我假设 "%FILE_PATH%""%OUTPUT_DIR%" 不应使用 \
  • 谢谢,将命令更改为robocopy "%FILE_PATH%\" "%OUTPUT_DIR%" \"%FILE_NAME%\" /R:5 /W:2 /V /LOG+:"%ROBO_LOG%\" 可以稍微推进一下。现在问题出在LOG 参数和%FILE_NAME% 内部有空格。
  • 为什么还要包含反斜杠?我告诉过你,你不能那样做! (它们实际上是在转义它们前面的双引号)。在不阅读您的任何代码的情况下,我希望它看起来更像这样:%SystemRoot%\System32\Robocopy.exe "%FILE_PATH%" "%OUTPUT_DIR%" "%FILE_NAME%" /R:5 /W:2 /V /LOG+:"%ROBO_LOG%"
  • 当您使用%%~dpI 时,resiiulting 路径将有一个尾部反斜杠。因为后面的反斜杠会有效地避开双引号,你需要防止这种情况发生。最简单的方法是给它添加一个句点,%%~dpI.

标签: batch-file variables path command-prompt robocopy


【解决方案1】:

这是一个快速的重写,纠正了一些事情,删除了不必要的事情,并将“数组”项的迭代更改为更简单的东西:

Rem Define array of input files to copy
Set "MASTER_SOURCE=\\path\with\some file\and messy. folder name\bla bla --- bla\stuff"
Set "SOURCE_FILES[0]=%MASTER_SOURCE%\this file with a pesky name.csv"
Set "SOURCE_FILES[1]=%MASTER_SOURCE%\this other file with a pesky name.csv"

Rem Define output file path
Set "OUTPUT_ROOT=C:\Users\me\stuff and things\save here"

Rem Create dated folder within the OUTPUT_ROOT location
Rem Obtain date/time timestamps
Set "dt="
Rem Source: https://stackoverflow.com/a/19706067/1655567
For /F "Tokens=2 Delims==" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe OS Get
 LocalDateTime /Value 2^>NUL') Do Set "dt=%%~nG"

If Not Defined dt GoTo :EOF

Rem Define output path
Set "OUTPUT_DIR=%OUTPUT_ROOT%\%dt:~0,4%-%dt:~4,2%-%dt:~6,2%_%dt:~8,2%-%dt:~10,2%-%dt:~12,2%"

Rem Define robocopy log file
Set "ROBO_LOG=%OUTPUT_DIR%\robocopy.log"

Echo(
Echo Progressing messy file copying

Rem Iterate over array elements and copy files
For /F "Tokens=1,* Delims==" %%G In ('"(Set SOURCE_FILES[) 2>NUL"') Do (
    Echo Copying: %%H
    %SystemRoot%\System32\Robocopy.exe "%%~dpH." "%OUTPUT_DIR%" "%%~nxH" /R:5 /W:2 /V /LOG+:"%ROBO_LOG%"
    Echo Finished copying: %%H
)

【讨论】:

  • 非常感谢您的有用回答。与我的解决方案相比,使用For /F "Tokens=1,* Delims==" %%G In ('"(Set SOURCE_FILES[) 2>NUL"') 有什么好处?第二个问题,对于 cmets 使用 Rem 而不是 :: 有什么好处吗?
  • 好处是您不需要使用延迟扩展,(或者在您的情况下尝试使用带有callsetting 临时变量的变通方法)我>。 Rem 用于备注,是提供内联备注的正确官方方式。 :: 是一个 hack,它本质上是一个损坏的标签,因此只是一个通常什么都不做的命令行。但是,如果您尝试在带括号的块中使用损坏的标签,则在某些情况下可能会使您的代码出错。我的建议是永远使用:: 而不是正确的Rem 命令。
  • 为我上面的错别字道歉。在倒数第二句lables 应读作labels,在最后一句中,ever 应读作never
猜你喜欢
  • 1970-01-01
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
相关资源
最近更新 更多