how to make batch file handle spaces in file names

15,555

See the following answers on Stack Overflow:

  1. How to set environment variables with spaces?
    Why is no string output with 'echo %var%' after using 'set var = text' on command line?
    They explain the recommended syntax set "VariableName=variable value" to define an environment variable and the reasons recommending this syntax.
  2. Why does ECHO command print some extra trailing space into the file?
    It explains why the space character left to redirection operator > on an ECHO command line is also written into the file as trailing space and how to avoid this safely on variable text written into the file.
    See also Microsoft documentation about Using command redirection operators.
    On other command lines than ECHO a space left to > is usually no problem.

It is in general wrong to use multiple times " within an argument string like a file or folder path. There should be just one " at beginning and one " at end. This is explained by help of Windows command processor output on last help page on running in a command prompt window cmd /?.

The Microsoft documentation about Naming Files, Paths, and Namespaces explains that the directory separator on Windows is \ and not / and therefore / should not be used in batch files on Windows in file/folder paths.

The help output on running in a command prompt window call /? explains how the arguments of a batch file can be referenced with which modifiers.

The code rewritten according to information posted above and on the referenced pages:

@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

The first line in tmp.txt contains the second argument as passed to the batch file, i.e. without or with surrounding double quotes.

The following code is necessary to write the second argument safely always without " into file tmp.txt even on second argument passed to the batch file is "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 cannot be used as not working for something like "Hello & welcome!". Windows command processor would interpret the first string separated by normal space, horizontal tab, comma, equal sign, or no-break space (in OEM code pages) delimited string after & as command or application to execute as described by single line with multiple commands using Windows batch file.

"tmp.txt" could be written everywhere in both batch files also with just tmp.txt. But it is never wrong to enclose the complete file/folder argument string in double quotes even on not being really necessary because of the string does not contain a space or one of these characters &()[]{}^=;!'+,`~. So it is good practice to always enclose a complete file/folder argument string in double quotes. For example running a replace on both batch files searching for tmp.txt and using as replace string %TEMP%\%~n0.tmp would result in using instead of tmp.txt in current directory a temporary file with name of batch file as file name and file extension .tmp in directory for temporary files independent on what is the name of the batch file and what is the path of the directory for temporary files.

The last suggestion is reading this answer for details about the commands SETLOCAL and ENDLOCAL.

The temporary file should be also deleted finally before reaching an exit point for batch file execution.

Share:
15,555
Sophie
Author by

Sophie

Updated on June 04, 2022

Comments

  • Sophie
    Sophie about 2 years

    I have the following batch file to make git diff invoke spreadsheet compare UI in windows. So I'm trying to pass the git diff's 2nd (old file) and 5th (new file) arguments to spreadsheet compare in order to make it compare the file using git diff.

    So now, this batch file only successfully handles files with NO spaces in the file names, it CANNOT handle files with spaces in the file names.

    What code should I add to this script to make this batch code handles file with spaces:

    @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
    

    It currently throw errors like this:

    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