繁体   English   中英

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

[英]Batch file with spaces in variables/filenames in text file

我根本没有接受过编码方面的教育,所以你不得不原谅任何可怜的术语!

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

它创建一个新目录,然后通过另一个目录及其所有子目录查找.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. 批处理文件所在目录的路径包含空格(或其他特殊字符)

我试过用这样的引号括起来:

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

forfiles在目录名称中找到空格,就会在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 . . .

从我已经完成的研究中我可以看到这种性质的问题得到了很多的问题 - 为了增加堆积而道歉但是由于我的知识有限,我恐怕我根本无法自己解决这个问题!

要避免路径和文件名中包含空格的问题,请使用引号。 但是当涉及到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% ,所以我不得不为for /f添加usebackq选项,因为它会将变量%LIST%的值视为文字字符串而不是文件;
  • 之后的路径/p以及后的图案/mforfiles括在括号中; 这里非常重要的是/p之后的路径没有\\终止,因为这将被forfiles解释为转义字符以转义结束引号" ; 如果你不能确保%FILESPATH%满足该条件,则写/p "%FILESPATH%\\."而不是 编辑:最后一个语句错了!
  • @path变量扩展为已经引用的字符串,所以一切都很好;
  • 棘手的部分是来自原始代码的目标文件%DEST%\\@file ,因为@file扩展为已经引用的字符串,因此结果将类似\\...\\00FoundImages\\"FoundImage 1.png" ,for实例; 所以引用整个表达式如0x22%DEST%\\@file0x22 1会导致"\\...\\00FoundImages\\"FoundImage 1.png"" ,因此文件名FoundImage 1.png对命令解释器不引用; 使用0x22%DEST%0x22\\@file 1将导致"\\...\\00FoundImages"\\"FoundImage 1.png" ,它不会伤害许多命令,但可能会影响某些命令,而且它根本就不漂亮; 为了解决这个问题,只需首先通过cd /d 0x22%DEST%0x22 1更改到目录%DEST% ,所以单独说明,然后仅使用@file作为move命令行;
  • 最后, forfiles返回匹配的文件目录,因此为了确保只处理文件,我实现了if查询;

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

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运行命令的引号内的引号必须使用反斜杠进行转义。 但不是其他引用,如启动文件夹。

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

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文件名和扩展名,因为我不知道%LIST%文件内容并假设一个完全限定的文件名列表);
  • important :仅显示 move命令用于调试目的; 删除前面的ECHO以使其运行,不会比调试好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM