3

I have a batch file to process each Excel file found by FOR with a wildcard pattern with a Java application:

for %%i in ("../test data/sprint4/*.xls") do (
    @echo "%%~fi"
)

I am running this batch file for example from

C:\dir1\dir2\dir3

and there is the file

C:\dir1\dir2\test data\sprint4\myfile.xlx

The output file name with full path is

C:\dir1\dir2\myfile.xls

test data\sprint4 is missing in the path and I am not sure what is wrong.

Someone suggested using /?, but when I do echo /? there is a very limited amount of information:

echo /?
Displays messages, or turns command-echoing on or off.

ECHO [ON | OFF]
ECHO [message]

Type ECHO without parameters to display the current echo setting.

This really does not explain usage of wildcards. Searches did not help either. So now I am stuck.

Why is full path of Excel files found in a directory specified with a relative path using wildcard pattern *.xls in above FOR loop wrong?

Mofi
  • 46,139
  • 17
  • 80
  • 143
Tony
  • 1,127
  • 1
  • 18
  • 29

3 Answers3

2

Use backslashes for Window's paths instead of forward slashes.

for %%i in ("..\test data\sprint4\*.xls") do (
    @echo "%%~fi"
)
Tim
  • 2,701
  • 3
  • 26
  • 47
2

Run in a command prompt window for /? to get output the several display pages long help for this command.

And the directory separator on Windows is \ and not / whereby Windows command interpreter often (but not always) corrects this as it can be seen on running the batch file from within a command prompt because command interpreter prints to console what is really processed after parsing a command line respectively command block. In this case the slashes are not automatically corrected to backslashes resulting in wrong paths for the found files.

However, full path finding of command FOR is sometimes not working as expected from relative paths. The code in question is one example.

Solution 1 is using predefined environment variable CD containing path of Current Directory not ending with a backslash except the current directory is the root of a drive which can't occur here.

for %%i in ("%CD%\..\test data\sprint4\*.xls") do (
    @echo "%%~fi"
)

The current directory can be different to directory of the batch file.

Solution 2 is using drive and path of the batch file referenced with %~dp0 whereby this path always ends with a backslash.

for %%i in ("%~dp0..\test data\sprint4\*.xls") do (
    @echo "%%~fi"
)

Run in a command prompt window call /? for details on %~dp0 and set /? for details on CD and other predefined environment variables.

Solution 3 is using relative path, but with backslashes:

for %%i in ("..\test data\sprint4\*.xls") do (
    @echo "%%~fi"
)

Now name of found *.xls files are always with correct full path.

Mofi
  • 46,139
  • 17
  • 80
  • 143
2

As others have pointed out, you should use \ instead of /, and that solves your problem.

As to why / fails... There are a number of contexts where / works, and some where it does not, and some where it appears to work, but gives the wrong result. See Why does the cmd.exe shell on Windows fail with paths using a forward-slash ('/'') path separator?.

You have discovered another case where it "works", but gives the wrong result. The problem is that %%i while using / gives the found file name and extension only, so when you ask for the full path with %%~fi, it uses the current directory, and you get your wrong result.

for %%i in ("../test data/sprint4/*.xls") do @echo "%%i" --^> "%%~fi"

yields:

"myfile.xlx" -->  "C:\dir1\dir2\test data\sprint4\myfile.xlx"

But if you switch to back slashes, then the original relative path is preserved, so %%~fi gives the correct result:

for %%i in ("..\test data\sprint4\*.xls") do @echo "%%i" --^> "%%~fi"

yields:

"..\test data\sprint4\myfile.xlx" --> "C:\dir1\dir2\test data\sprint4\myfile.xlx"

On my machine, I seem to get the correct answer with the FOR loop if my path contains at least one \. But I would not rely on that because there are so many cases where / can fail. Best to get in the habit of always using \ in all cases.

Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • I guess it is just a psychological thing for me with a unix/linux background, \ always escapes characters ;-) This gets to be a big problem in java. Sometimes you have to use \\\\. But cmd is different so I will replace the / with \ – Tony Jun 02 '16 at 14:14