variables - 文本文件中变量/文件名中带有空格的批处理文件

标签 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. 批处理文件所在目录的路径包含空格(或其他特殊字符)

我尝试用引号括起来,如下所示:

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”的目录运行批处理文件时,错误已写入 error.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% ,所以我必须添加 usebackq选项 for /f ,因为它会处理变量 %LIST% 的值作为文字字符串而不是文件;
  • /p之后的路径以及 /m 之后的模式的forfiles括在括号内;这里非常重要的是 /p 之后的路径\ 终止,因为这会被 forfiles 解释为转义字符逃避结束语 " ; 如果您不能保证 %FILESPATH%满足该标准,请写 /p "%FILESPATH%\."相反; 编辑:最后一个语句是错误的!
  • @path变量扩展为已引用的字符串,因此一切都很好;
  • 棘手的部分是目标文件 %DEST%\@file来自您的原始代码,因为 @file扩展为已引用的字符串,因此结果将类似于 \...\00FoundImages\"FoundImage 1.png" , 例如;因此引用整个表达式,如 0x22%DEST%\@file0x22 1 将导致 "\...\00FoundImages\"FoundImage 1.png"" ,因此文件名为 FoundImage 1.png对命令解释器来说似乎未加引号;使用0x22%DEST%0x22\@file 1 将导致 "\...\00FoundImages"\"FoundImage 1.png" ,这不会损害许多命令,但可能会影响一些命令,而且它根本不美观;要解决这个问题,只需更改为目录 %DEST%首先由cd /d 0x22%DEST%0x22 1,所以单独声明,那就用@file仅适用于move命令行;
  • 最后,forfiles返回匹配的文件目录,因此为了确保仅处理文件,我实现了 if查询;
<小时/>

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

关于variables - 文本文件中变量/文件名中带有空格的批处理文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39339278/

相关文章:

cocoa - 如何以编程方式将一个 Terminal.app 窗口移动到另一个空间?

java - 如何在映射 :util element in a spring xml file when the string is defined in the same file? 中引用字符串变量

JavaScript 变量列表和编辑器

c++ - 在 C++ 中使用变量创建部分文件名

PHP 模板

linux - 相当于 sh 中的 %~dp0(检索源文件名)

batch-file - 意外使用 ( 批处理文件

javascript - 批处理文件转换和使用

python - 目录路径python中的空格

math - 全局变换到局部变换?