Richard Schaefer
Richard Schaefer

Reputation: 595

Recursive directory processing in a BAT file with a twist

OK, I apologize ahead of time for a) using an old, crappy technology (BAT files) and b) asking what seems to be a redundant question. I'm limited in the technology I'm allowed to use in this particular case and after looking at dozens of posts on the subject I can't find anything I can adapt to what I need.

I have a directory structure that looks like this: A B C D etc... XYZ more folders

My BAT file is located outside this files system. I need to inspect it starting at level "C" and need to find the "XYZ" directory. The folders between C and XYZ can have variable names depending on the environment in which the files were created. I need to end up with a string that consists of the directory names from C through XYZ (i.e. "C\D\E\F....\XYZ") that I can put into a variable so when my BAT file is completed I can reference the variable and run another command.

I've looked at posts using FIND and FOR but I can't seem to figure out how to a) limit the string to the starting directory (for example when I combine FOR with DIR I get "A\B\C...") and how to stop when I get to "XYZ"...

Any help is greatly appreciated.

Upvotes: 0

Views: 274

Answers (2)

dbenham
dbenham

Reputation: 130819

This should work in most situations:

@echo off
setlocal enableDelayedExpansion

set "root=c:\a\b\c"
set "target=xyz"

for %%R in ("%root%") do for /f "delims=" %%F in (
  'dir /b /s /ad "%root%\%target%"'
) do (
  set "fullPath=%%F"
  set "relpath=!fullPath:%%~dpR=!"
)
echo !relpath!

It can fail if any of your paths contain ! or =. There are solutions for this, but the code is significantly more complicated.

EDIT

Actually, there is a relatively simple solution using FORFILES that should work in all situations. (Assuming your version of Windows has FORFILES)

@echo off
setlocal disableDelayedExpansion

set "root=c:\a\b\c"
set "target=xyz"

for /f "delims=" %%F in (
  'forfiles /p "%root%" /m "%target%" /s /c "cmd /c if @isdir==TRUE echo @relpath"'
) do set "relpath=%%~F"
for %%R in ("%root%") do set "relpath=%%~nxR%relpath:~1%"
echo %relpath%

The only restriction is the code has to change slightly if your result contains poison characters like &. In that case you need to add quotes to the final ECHO statement, or else enable delayed expansion at the end and use echo !relpath!

Upvotes: 1

LS_ᴅᴇᴠ
LS_ᴅᴇᴠ

Reputation: 11151

For a) question:

FOR /F "TOKENS=*" %%d IN ('DIR A\B\C\XYZ /S /AD /B') DO SET variable=%%d

For a) and b) question:

FOR /D /R "A\B\C" %%d IN (*.*) DO IF /I "%%~nxd"=="XYZ" (SET variable=%%d& GOTO :EOF)

but this will exit batch script, so you need:

... your batch code
CALL :GET_XYZ
... your batch code
GOTO :EOF

:GET_XYZ
FOR /D /R "A\B\C" %%d IN (*.*) DO IF /I "%%~nxd"=="XYZ" (SET variable=%%d& GOTO :EOF)
ECHO XYZ not found!
GOTO :EOF

Upvotes: 0

Related Questions