在文本文件中的变量/文件名中包含空格的批处理文件

时间:2016-09-06 01:02:35

标签: variables batch-file spaces

我从未接受过编码方面的教育,所以你不得不原谅任何不好的术语!

我从网络上选择了一些批处理文件的代码(其中一些来自这个网站),我试图重写其中一些以满足我的需求。

它创建一个新目录,然后通过另一个目录及其所有子目录查找.txt列表中的文件名,然后将这些文件复制到开头创建的目录中。列表中找不到的任何文件都会写入另一个文本文件中,以跟踪丢失的任何内容。

代码是:

md 00FoundImages

set LIST=%cd%\imagelist.txt
set FILESPATH=%cd%\testimages
set DEST=%cd%\00FoundImages

for /f "delims=" %%x in (%LIST%) do (forfiles /p %FILESPATH% /s /m %%x* /c "cmd /c move /y @path %DEST%\@file" 2>>errors.txt)

在大多数情况下都可以正常工作,但以下情况除外:

  1. 文本文件中的文件名包含空格
  2. 批处理文件所在目录的路径包含空格(或其他特殊字符)
  3. 我试过用这样的引号括起来:

    set FILELIST="%cd%\imagelist.txt"
    set FILESPATH="%cd%\testimages"
    set DESTPATH="%cd%\00FoundImages"
    

    只要在目录名称中找到空格,就会在forfiles命令失败。

    当我在引号中使用变量时,我已尝试将变量括起来:

    for /f "delims=" %%x in ("%LIST%") do (forfiles /p "%FILESPATH%" /s /m %%x* /c "cmd /c move /y @path "%DEST%\@file"" 2>>errors.txt)
    

    当我从名为'testing - Copy'的目录运行批处理文件时,我将错误写入我的errors.txt文件

    ERROR: Invalid argument/option - '-'.
    Type "FORFILES /?" for usage.
    

    这是正在发生的事情的印刷品:

    E:\ImageAutomationStuff\testing - Copy>md 00FoundImages
    A subdirectory or file 00FoundImages already exists.
    
    E:\ImageAutomationStuff\testing - Copy>set LIST=E:\ImageAutomationStuff\testing - Copy\imagelist.txt
    
    E:\ImageAutomationStuff\testing - Copy>set FILESPATH=E:\ImageAutomationStuff\testing - Copy\testimages
    
    E:\ImageAutomationStuff\testing - Copy>set DEST=E:\ImageAutomationStuff\testing - Copy\00FoundImages
    
    E:\ImageAutomationStuff\testing - Copy>pause
    Press any key to continue . . .
    
    E:\ImageAutomationStuff\testing - Copy>for /F "delims=" %x in ("E:\ImageAutomationStuff\testing - Copy\imagelist.txt") do (forfiles /p "E:\ImageAutomationStuff\testing - Copy\testimages" /s /m %x* /c "cmd /c move /y @path "E:\ImageAutomationStuff\testing - Copy\00FoundImages\@file""  2>>errors.txt )
    
    E:\ImageAutomationStuff\testing - Copy>(forfiles /p "E:\ImageAutomationStuff\testing - Copy\testimages" /s /m E:\ImageAutomationStuff\testing - Copy\imagelist.txt* /c "cmd /c move /y @path "E:\ImageAutomationStuff\testing - Copy\00FoundImages\@file""  2>>errors.txt )
    
    E:\ImageAutomationStuff\testing - Copy>pause
    Press any key to continue . . .
    

    从我所做的研究中我可以看到很多这样的问题被提出了很多问题 - 为了加入这一堆而道歉但是由于我的知识有限,我恐怕我根本无法解决这个问题!

3 个答案:

答案 0 :(得分:1)

为避免路径和文件名中出现空格问题,请使用引号。但是在forfiles时需要注意,因为所有与路径和文件名相关的@ - 变量都会扩展为""中已包含的值,因此很容易恰好有双引号值。

我会尝试一下:

md "%cd%\00FoundImages"

set "LIST=%cd%\imagelist.txt"
set "FILESPATH=%cd%\testimages"
set "DEST=%cd%\00FoundImages"

for /f "usebackq delims=" %%x in ("%LIST%") do (
    forfiles /p "%FILESPATH%" /s /m "%%x*" /c "cmd /c if @isdir==FALSE cd /d 0x22%DEST%0x22 & move /y @path @file" 2>>errors.txt
)

我做了什么:

  • 改进了set的语法,以便整个赋值表达式包含在""中;这避免了一些特殊字符的问题,但引号是不是变量值的一部分;
  • 引用%LIST%,因此我必须将usebackq选项添加到for /f,因为它会将变量%LIST%的值视为文字字符串而不是文件否则;
  • /p之后的路径以及/m forfiles之后的模式括在括号中;这里/p之后的路径 <{1}}终止路径非常重要,因为这会被\解释为逃避字符以逃避收尾报价forfiles; 如果您无法确保"符合该标准,请改为编写%FILESPATH%; 编辑:最后一条语句错误!
  • /p "%FILESPATH%\."变量扩展为已经引用的字符串,所以一切都很好;
  • 棘手的部分是原始代码中的目标文件@path,因为%DEST%\@file扩展为已引用的字符串,因此结果类似于@file;所以引用像\...\00FoundImages\"FoundImage 1.png" 1 这样的整个表达式会导致0x22%DEST%\@file0x22,因此文件名"\...\00FoundImages\"FoundImage 1.png""看起来没有引用到命令解释器;使用FoundImage 1.png 1 会导致0x22%DEST%0x22\@file,这不会伤害许多命令,但可能会影响某些命令,而且它根本就不漂亮;为了解决这个问题,只需首先通过"\...\00FoundImages"\"FoundImage 1.png" 1 更改到目录%DEST%,因此单独说明,然后仅对{{1}使用cd /d 0x22%DEST%0x22命令行;
  • 最后,@file返回匹配的文件目录,因此为了确保只处理文件,我实现了move查询;

1)... forfiles表达式代表if命令表达式中的0x22字符,并以十六进制表示法表示其字符代码;我更喜欢这种指定引号的方法,因为另一个选项"可能会影响命令行解释器,因为它不支持反斜杠转义,因此它识别引号,这可能会无意中改变其行为。 /子>

答案 1 :(得分:0)

for /f "delims=" %%x in ("%LIST%") do (forfiles /p "%FILESPATH%" /s /m %%x* /c "cmd /c move /y @path \"%DEST%\@file\"" 2>>errors.txt)

命令forfiles运行的引号中的引号必须使用反斜杠进行转义。但不是其他引用,如启动文件夹。

答案 2 :(得分:0)

虽然我不明白为什么你将FORFILES循环嵌套在另一个(FOR /F)循环中,但下一个代码片段应该可以解决这个问题:

for /f "usebackq delims=" %%x in ("%LIST%") do (
  forfiles /p "%FILESPATH%" /s /m "%%~nxx" /c "cmd /c ECHO move /y @path \"%DEST%\"\@file" 2>>errors.txt
)

注意:

  • "%FILESPATH%""%%~nxx";
  • 中的双引号
  • \"%DEST%\";
  • 中转义了双引号
  • plain @path@file,因为这些FORFILES命令变量已经双引号;
  • 也许您需要重新构造/m "%%~nxx"文件掩码(我使用%%~nxx file name and extension因为我不知道%LIST%文件内容并假设一个完全限定的文件名列表);
  • 重要的move命令仅用于显示以进行调试;删除之前的ECHO以使其正常运行,而不是调试。