1

I want to run a FOR LOOP to create files using the variables that it returns, and then modify the resulting variables and output.

I am trying to create files based upon the parent folder name, which contain the children in the output file, and then append a string to the beginning of each line in the output file.

REM THIS SECTION IS JUST TO RECREATE MY ISSUE.  THESE FILES AND FOLDERS ALREADY EXIST.  
REM THEY ARE NOT SEQUENTIAL AND HAVE RANDOM NAMES.
REM ==================================================================

md %temp%\looptest\folder1\subfolder1
md %temp%\looptest\folder2
md %temp%\looptest\folder3

echo echo folder2-file1-line1 >> %temp%\looptest\folder2\folder2-file1.bat
echo echo folder2-file1-line2 >> %temp%\looptest\folder2\folder2-file1.bat
echo echo folder2-file1-line3 >> %temp%\looptest\folder2\folder2-file1.bat
echo echo folder2-file2-line1 >> %temp%\looptest\folder2\folder2-file2.bat
echo echo folder2-file2-line2 >> %temp%\looptest\folder2\folder2-file2.bat
echo echo folder2-file2-line3 >> %temp%\looptest\folder2\folder2-file2.bat
echo echo folder2-file3-line1 >> %temp%\looptest\folder2\folder2-file3.bat
echo echo folder2-file3-line2 >> %temp%\looptest\folder2\folder2-file3.bat
echo echo folder2-file3-line3 >> %temp%\looptest\folder2\folder2-file3.bat

echo echo folder3-file1-line1 >> %temp%\looptest\folder3\folder3-file1.bat
echo echo folder3-file1-line2 >> %temp%\looptest\folder3\folder3-file1.bat
echo echo folder3-file1-line3 >> %temp%\looptest\folder3\folder3-file1.bat
echo echo folder3-file2-line1 >> %temp%\looptest\folder3\folder3-file2.bat
echo echo folder3-file2-line2 >> %temp%\looptest\folder3\folder3-file2.bat
echo echo folder3-file2-line3 >> %temp%\looptest\folder3\folder3-file2.bat
echo echo folder3-file3-line1 >> %temp%\looptest\folder3\folder3-file3.bat
echo echo folder3-file3-line2 >> %temp%\looptest\folder3\folder3-file3.bat
echo echo folder3-file3-line3 >> %temp%\looptest\folder3\folder3-file3.bat

echo echo subfolder1-file1-line1 >> %temp%\looptest\folder1\subfolder1\subfolder1-file1-extratext.bat
echo echo subfolder1-file1-line2 >> %temp%\looptest\folder1\subfolder1\subfolder1-file1-extratext.bat
echo echo subfolder1-file1-line3 >> %temp%\looptest\folder1\subfolder1\subfolder1-file1-extratext.bat
echo echo subfolder1-file2-line1 >> %temp%\looptest\folder1\subfolder1\subfolder1-file2-extratext.bat
echo echo subfolder1-file2-line2 >> %temp%\looptest\folder1\subfolder1\subfolder1-file2-extratext.bat
echo echo subfolder1-file2-line3 >> %temp%\looptest\folder1\subfolder1\subfolder1-file2-extratext.bat
echo echo subfolder1-file3-line1 >> %temp%\looptest\folder1\subfolder1\subfolder1-file3-extratext.bat
echo echo subfolder1-file3-line2 >> %temp%\looptest\folder1\subfolder1\subfolder1-file3-extratext.bat
echo echo subfolder1-file3-line3 >> %temp%\looptest\folder1\subfolder1\subfolder1-file3-extratext.bat


REM THIS IS WHERE MY ACTUAL QUESTION STARTS
REM ========================================================

setlocal enabledelayedexpansion

FOR /F "delims=" %%G IN ('dir /a:d /b /s %temp%\looptest\') DO (

    set "var=%%G"
    set "var=!var:%temp%\looptest\=!

    (
        dir /b %temp%\looptest\!var!

    )>>"%temp%\looptest\!var!-output.bat"


)

folder1-output.bat is unusable because there are no files in it's child folder, only another folder, and that's ok, I can ignore it if needed.

Right now, the file folder2-output.bat contains the lines:

folder2-file1.bat
folder2-file2.bat
folder2-file3.bat

I want folder2-output.bat to contain the lines:

call folder2-file1.bat
call folder2-file2.bat
call folder2-file3.bat

I want folder3-output.bat to contain the lines:

call folder3-file1.bat
call folder3-file2.bat
call folder3-file3.bat

I want folder1\subfolder1-output.bat to contain the lines:

call subfolder1-file1-extratext.bat
call subfolder1-file2-extratext.bat
call subfolder1-file3-extratext.bat

But I can't figure out where to echo out the CALL command to add to the FOR LOOP.

I think I need to do something like

    set "var2=%%G"
    set "var2=CALL !var2!

and then

ECHO !var2! !var! >>"%temp%\looptest\!var!-output.bat"

But I'm not sure where to put that in the FOR loop.

2 Answers 2

2
@ECHO OFF
SETLOCAL
SET "sourcedir=%temp%\looptest"
FOR /d /r "%sourcedir%" %%G IN (*) DO (
 ECHO examining directory "%%G"
 rem if the directory contains any .bat files then create a file
 rem called leafname-output.bat in the parent containing
 rem "call each-batfilename-found"
 IF EXIST "%%G\*.bat" (
  ECHO "%%G" contains batchfiles
  ECHO "%%~dpG" is parent
  ECHO "%%~nxG" is leafname
  FOR /f "delims=" %%a IN ('DIR /b /a-d "%%G\*.bat"') DO >>"%%G-output.bat" ECHO CALL "%%~nxa"
 ) ELSE (
  ECHO "%%G" does NOT contain batchfiles
 )
 ECHO -------------------------------------
)

dir/s "%sourcedir%\*-output.bat"

GOTO :EOF

Interesting little adventure. Excellent that you provided code to create your testfiles - but it appears that you've sensibly changed your temp directory to a location not containing spaces, so I'm not sure it'd work with a vanilla installation.

You have evidently studied delayedexpansion but it appears you've become more concerned with the method of solving the problem than targeting the solution.

I believe the echoes and commentary above adequately document the method I chose after analysing your method to determine the problem to be solved. You will no doubt now put a magnifying glass on the various uses of for as documented in for /? and with many examples here on SO. Of course, I may have missed the mark.

Naturally, if you do not delete the *-output.bat files before you start, you may encounter problems since the files are appended to and the dir looking for *.bat files will include the ...-output.bat in the list delivered. Should be easily solved using a mutation of the final dir/s command listed.

Sign up to request clarification or add additional context in comments.

1 Comment

The For /D /R looks quite similar ;-) +1
1

For local testing on my Ramdisk A: I changed and simplified your batch:

:: Q:\Test\2019\08\13\SO_57482013.cmd
@Echo off
Set "Base=A:\Test"
:: create folders
for %%D in (folder1\subfolder1 folder2 folder3) Do md "%Base%\looptest\%%D"
:: create files
for %%D in (folder2 folder3
) Do for /l %%F in (1,1,3
) Do for /l %%L in (1,1,3
) Do echo echo %%D-file%%F-line%%L >>"%Base%\looptest\%%D\%%D-file%%F.bat"
for /l %%F in (1,1,3
) Do for /l %%L in (1,1,3
) Do echo echo subfolder1-file%%F-line%%L >> "%Base%\looptest\folder1\subfolder1\subfolder1-file%%F-extratext.bat"

This creates the following folder/file structure (with all files containing line1..3):

> tree a:\ /F
A:\
└───Test
    └───looptest
        ├───folder1
        │   └───subfolder1
        │           subfolder1-file1-extratext.bat
        │           subfolder1-file2-extratext.bat
        │           subfolder1-file3-extratext.bat
        │
        ├───folder2
        │       folder2-file1.bat
        │       folder2-file2.bat
        │       folder2-file3.bat
        │
        └───folder3
                folder3-file1.bat
                folder3-file2.bat
                folder3-file3.bat

IMO you are missing to include the folder name when calling the batch in the folder, this changed routine will do:

REM THIS IS WHERE MY ACTUAL QUESTION STARTS
REM ========================================================

FOR /D /R "%Base%\looptest" %%G IN (*) Do (
  For %%F in (%%G\*.bat) Do Echo @Call %%~nxG\%%~nxF
) >"%%~dpG%%~nxG-output.bat"

So for example A:\Test\looptest\folder2-output.bat contains:

@Call folder2\folder2-file1.bat
@Call folder2\folder2-file2.bat
@Call folder2\folder2-file3.bat

And when executed from within folder A:\Test\looptest yields:

folder2-file1-line1
folder2-file1-line2
folder2-file1-line3
folder2-file2-line1
folder2-file2-line2
folder2-file2-line3
folder2-file3-line1
folder2-file3-line2
folder2-file3-line3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.