如何使批处理文件处理文件名中的空格

4

我有以下批处理文件,用于在Windows中使git diff调用电子表格比较UI。因此,我尝试将git diff的第二个(旧文件)和第五个(新文件)参数传递给电子表格比较,以便使用git diff比较文件。

现在,这个批处理文件只能成功处理文件名不含空格的文件,无法处理文件名包含空格的文件。

为了使这个批处理文件处理带有空格的文件名,您应该添加什么代码?

@ECHO OFF
set path2=%5
set path2=%path2:/=\%
ECHO %2 > tmp.txt
dir %path2% /B /S >> tmp.txt

C:/"Program Files"/"Microsoft Office"/root/vfs/ProgramFilesX86/"Microsoft Office"/Office16/DCF/SPREADSHEETCOMPARE.EXE tmp.txt

它目前会抛出以下错误:

Unhandled Exception: System.ArgumentException: Illegal characters in path.
   at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
   at System.IO.Path.GetFileName(String path)
   at ProdianceExcelCompare.Form1.StatusReady()
   at ProdianceExcelCompare.Form1.Init()
   at ProdianceExcelCompare.Form1..ctor(String instructionFile)
   at ProdianceExcelCompare.Program.Main(String[] args)
fatal: external diff died, stopping at London comparison.xlsx

1
当您发送参数时,带有毒药或空格字符的参数需要用双引号括起来。在批处理文件中,如果您不再需要周围的双引号,则可以使用%~5而不是%5来删除它们。此外,set命令的推荐语法是Set "VariableName=VariableValue"。因此,我建议在您的脚本中使用以下内容:Set "path2=%~5",以删除周围的双引号,或者如果您想保留它们,则使用Set "path2=%5" - Compo
标准的Windows路径分隔符是\而不是/(尽管由于一些智能自动校正,有些命令可能会接受两者)! - aschipfl
2个回答

2
请参考Stack Overflow上的以下答案:
  1. 如何设置带有空格的环境变量?
    在命令行中使用“set var = text”后,“echo %var%”没有输出任何字符串?
    它们解释了推荐使用语法 set "VariableName=variable value" 来定义环境变量以及推荐此语法的原因。
  2. ECHO命令为什么会在文件中打印一些额外的尾随空格?
    它解释了为什么在ECHO命令行上留下重定向运算符 > 左侧的空格字符也会作为尾随空格写入文件中,以及如何安全地避免这种情况发生在写入文件中的文本变量上。
    还可以参考Microsoft关于 使用命令重定向运算符 的文档。
    在除ECHO之外的其他命令行上,左侧留有一个空格通常不会有问题。
一般来说,在文件或文件夹路径等参数字符串中多次使用 " 是错误的。应该只有一个 " 在开头和结尾。这是通过在命令提示符窗口中运行 cmd /? 命令后输出的 Windows 命令处理器帮助页面解释的。
Microsoft 关于文件、路径和命名空间的命名的文档解释了在 Windows 上目录分隔符是 \ 而不是 /,因此在 Windows 批处理文件中不应该在文件/文件夹路径中使用 /
在命令提示符窗口中运行 call /? 命令的帮助输出解释了如何使用修饰符引用批处理文件的参数。
根据上述信息和引用页面重新编写的代码:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "path2=%~5"
set "path2=%path2:/=\%"
>"tmp.txt" echo %2
dir "%path2%" /B /S >>"tmp.txt" 2>nul

"%ProgramFiles%\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\DCF\SPREADSHEETCOMPARE.EXE" "tmp.txt"
endlocal

tmp.txt 文件中的第一行包含批处理文件传递的第二个参数,即带或不带双引号。

以下代码是为了始终安全地将第二个参数写入文件 tmp.txt,即使批处理文件传递的第二个参数是 "Hello & welcome!"

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "path2=%~5"
set "path2=%path2:/=\%"
set "Argument2=%~2"
setlocal EnableDelayedExpansion
echo !Argument2!>"tmp.txt"
endlocal 
dir "%path2%" /B /S >>"tmp.txt" 2>nul

"%ProgramFiles%\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\DCF\SPREADSHEETCOMPARE.EXE" "tmp.txt"
endlocal

">tmp.txt echo %~2" 不能使用,因为它无法处理类似于 "Hello & welcome!" 的内容。Windows 命令处理器会将第一个由普通空格、水平制表符、逗号、等号或非中断空格(在 OEM 代码页中)分隔的字符串解释为要执行的命令或应用程序,如 在 Windows 批处理文件中使用单行多个命令 中所述。
"tmp.txt" 可以在批处理文件中的任何地方被写入,也可以只用 "tmp.txt"。但是,即使不需要,将完整的文件/文件夹参数字符串括在双引号中也永远不会出错,因为该字符串不包含空格或这些字符之一:&()[]{}^=;!'+,`~。因此,始终将完整的文件/文件夹参数字符串括在双引号中是一个好习惯。例如,在两个批处理文件中运行替换操作,搜索 tmp.txt 并使用 %TEMP%\%~n0.tmp 作为替换字符串,将导致在临时文件目录中使用当前批处理文件的名称作为文件名和扩展名为 .tmp 的临时文件,而不管批处理文件的名称是什么,临时文件的路径是什么。

最后一个建议是阅读 this answer 了解有关命令 SETLOCALENDLOCAL 的详细信息。

在达到批处理文件执行的退出点之前,应该最终删除临时文件。


1

您可以按照以下方式使用引号:

它将引号中的字符串作为新命令窗口的标题处理。因此,您可以执行以下操作:

start "" "yourpath"

在下面的链接中找到了它: https://ccm.net/forum/affich-16973-open-a-file-with-spaces-from-batch-file
该链接提供了关于如何从批处理文件中打开带有空格的文件的信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接