In Windows, a batch file with a recursive for loop and a file name including blanks

9

7

I have a folder tree, like this (it's only an example, it will be deeper in my real case):

C:\test
|   
+---folder1
|       foo bar.txt
|       foobar.txt
|       
+---folder2
|       foo bar.txt
|       foobar.txt
|       
\---folder3
        foo bar.txt
        foobar.txt

My files have one or more spaces in the name and I need to perform a command on them, so I am interested in foo bar.txt but not in foobar.txt.

I tried (inside a batch file):

for /r test %%f in (foo bar.txt) do if exist %%f echo %%f

where the command is the simple echo.
It does not work because the space is skipped and I get no output.

This works but it is not what I need:

for /r test %%f in (foobar.txt) do if exist %%f echo %%f

It prints:

C:\test\folder1\foobar.txt
C:\test\folder2\foobar.txt
C:\test\folder3\foobar.txt

I tried using the quotation mark (") but it does not work:

for /r test %%f in ("foo bar.txt") do if exist %%f echo %%f

It does not work because the quotation mark is still included in the output:

C:\test\folder1\"foo bar.txt"
C:\test\folder2\"foo bar.txt"
C:\test\folder3\"foo bar.txt"

Alessandro Jacopson

Posted 2011-03-11T14:33:28.580

Reputation: 255

Answers

9

How about this?

for /f "tokens=* delims=" %%a in ('dir "c:\test\foo bar.txt" /s /b') do (
echo %%a
)

Craig H

Posted 2011-03-11T14:33:28.580

Reputation: 1 172

good idea to move the recursion in dir! Thank you. – Alessandro Jacopson – 2011-03-14T12:29:49.117

2

Without the recursive switch, you can tell FOR not to print the quotes:

for %%f in ("foo bar.txt") do @if exist %%f echo %~dpnxf

You might be able to do nested FOR statements. The outer would walk the directory tree and the inner would be the one above.

Paused until further notice.

Posted 2011-03-11T14:33:28.580

Reputation: 86 075

Hello, thank you for your answer. I edited the question, the tree can be deeper than just only one level and so I need the recursive for. – Alessandro Jacopson – 2011-03-11T15:54:14.160

2@uvts_cvs: FOR /R %%d in (.) DO for %%f ... is recursive, but there would be some things to work out to make it work. You may have to use delayed expansion, for example. SETLOCAL ENABLEDELAYEDEXPANSION and !varname!, etc. – Paused until further notice. – 2011-03-11T16:06:12.607

%~dpnf will omit the file extension. – dolmen – 2011-03-27T10:17:25.790

@dolmen: Fixed the typo. – Paused until further notice. – 2011-03-27T11:35:10.730

2

You might want to look at the forfiles command.

forfiles /S /M "* *" /C "cmd /C echo @PATH"

'/S' -- Recursion. Search all sub directories

'/M "* *"' -- File mask. Only search for files with a space in their name.

'/C "cmd /C echo @PATH"' -- Command. Issue this command on all files found.

Example output:

"C:\test\folder1\foo bar.txt"
"C:\test\folder2\foo bar.txt"
"C:\test\folder3\foo bar.txt"

Howler

Posted 2011-03-11T14:33:28.580

Reputation: 137

0

The flag f is the one you need to get an absolute filename witout quotes (so you can put quotes around if you need). But as it conflicts with the variable name you choose, you have to use another one:

for /r test %%i in ("foo bar.txt") do echo %%~fi

dolmen

Posted 2011-03-11T14:33:28.580

Reputation: 1 075

That's completely incorrect. There's no variable name conflict and quotes are printed by the command you show. – Paused until further notice. – 2011-03-27T11:41:19.397

0

Thanks, Dennis! I too was working on an almost identical problem. I wanted a bat file that I could pass in an input parm as a search string for filenames - recursively through directories. Just in case this is useful to someone else here it is.

::+++++++++
@echo off
setlocal ENABLEDELAYEDEXPANSION
for /R %%d in (.) do (
   for /f "usebackq" %%i in (`dir /b %%d ^| findstr /i %1`) do (
      echo Processing %%i
   )
)
endlocal

skippyV

Posted 2011-03-11T14:33:28.580

Reputation: 1