I want to run a .bat script which makes a file and save it with the same name as the folder it is in. I want it to start in a map and loop through the submaps. I started with this code below and run it in one of the submaps. That works, I get a file with the name of the submap.
FOR /D %%I IN ("%CD%") DO SET _LAST_SEGMENT_=%%~nxI
ECHO Last segment = "%_LAST_SEGMENT_%"
echo.>%_LAST_SEGMENT_%.mp4
pause
So now I only have to place it in a for loop. So I made the code below, which is not working. It seems that the %CD% is referring to my parent map(subfolders), where the .bat file is located, instead of my submaps (video1, video2, etc.).
Set Base=C:\Video\subfolders
FOR /R "%Base%" %%F IN (.) DO (
PushD "%%F"
FOR /D %%I IN ("%CD%") DO SET _LAST_SEGMENT_=%%~nxI
echo %CD%
ECHO Last segment = "%_LAST_SEGMENT_%"
echo.>%_LAST_SEGMENT_%.mp4
PopD
)
Pause
Output:
C:\Video\subfolders>Set Base=C:\Video\subfolders
C:\Video\subfolders>FOR /R "C:\Video\subfolders" %F IN (.) DO (
PushD "%F"
FOR / %I IN ("C:\Video\subfolders") DO SET _LAST_SEGMENT_=%~nxI
echo C:\Video\subfolders
ECHO Last segment = ""
echo. 1>.mp4
PopD
)
C:\Video\subfolders>(
PushD "C:\Video\subfolders\."
FOR / %I IN ("C:\Video\subfolders") DO SET _LAST_SEGMENT_=%~nxI
echo C:\Video\subfolders
ECHO Last segment = ""
echo. 1>.mp4
PopD
)
C:\Video\subfolders>SET _LAST_SEGMENT_=subfolders
C:\Video\subfolders
Last segment = ""
C:\Video\subfolders>(
PushD "C:\Video\subfolders\video1\."
FOR / %I IN ("C:\Video\subfolders") DO SET _LAST_SEGMENT_=%~nxI
echo C:\Video\subfolders
ECHO Last segment = ""
echo. 1>.mp4
PopD
)
C:\Video\subfolders\video1>SET _LAST_SEGMENT_=subfolders
C:\Video\subfolders
Last segment = ""
C:\Video\subfolders>(
PushD "C:\Video\subfolders\video2\."
FOR / %I IN ("C:\Video\subfolders") DO SET _LAST_SEGMENT_=%~nxI
echo C:\Video\subfolders
ECHO Last segment = ""
echo. 1>.mp4
PopD
)
C:\Video\subfolders\video2>SET _LAST_SEGMENT_=subfolders
C:\Video\subfolders
Last segment = ""
C:\Video\subfolders>(
PushD "C:\Video\subfolders\video3\."
FOR / %I IN ("C:\Video\subfolders") DO SET _LAST_SEGMENT_=%~nxI
echo C:\Video\subfolders
ECHO Last segment = ""
echo. 1>.mp4
PopD
)
C:\Video\subfolders\video3>SET _LAST_SEGMENT_=subfolders
C:\Video\subfolders
Last segment = ""
C:\Video\subfolders>Pause
Press any key to continue . . .
I saw the link below which explain to use setlocal enabledelayedexpansion but I can’t get this to work.
https://superuser.com/questions/503488/why-doesnt-cd-work-after-using-pushd-to-a-unc-path
Any advice would be appreciated
It looks like you want something like:
The commands
pushdandpopdare not really necessary as demonstrated with below code:The command FOR runs in a separate command process started with
cmd.exe /Cin background the command line:The command DIR outputs to handle STDOUT of this background command process
/Bjust all names with full path because of option/S/AD-H(attribute directory and not hidden)C:\Video\subfoldersand all its subdirectories.The error message output by DIR to handle STDERR on not finding any directory entry in entire directory tree of
C:\Video\subfoldersis suppressed by redirecting it to device NUL.Read the Microsoft article about Using Command Redirection Operators for an explanation of
2>nul. The redirection operator>must be escaped with caret character^on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embeddeddircommand line with using a separate command process started in background.FOR captures the output to STDOUT of started command process and processes this output line by line with ignoring empty lines and by default also lines starting with a semicolon which both do not occur here.
FOR would also split up every line into substrings on spaces/tabs and would assign just first space/tab separated string to specified loop variable
I. Directory names can have spaces and for that reasondelims=is used to define an empty list of string delimiters resulting in getting assigned to loop variableIalways the entire full qualified directory name currently processed from captured DIR output.The name of the directory without path is referenced with
%%~nxIwhich is the string after last backslash. A directory name can contain also a dot likefolder.nameor start with a dot like.FolderNamealthough both are unusual on Windows. For that reason it is necessary to use%%~nxI(name and extension) and not just%%~nIbecause of FOR does not verify if string referenced with%%Iis a file or directory name.%%~nIreferences the string between last\(or/for compatibility with Linux paths replaced all first by\) if there is any backslash (or slash) at all or beginning of string if there is no\(or/) and last dot if there is a.at all after already determined beginning of name string or end of string if there is no dot.%%~xIreferences the string beginning with last dot found after last directory separator. So the string assigned to loop variableImust not be a file/folder name of a really existing file/folder although this is the case here.%%~nxIwould be an empty string ifIholds a string ending with\(or/).Do not assign a string which can be referenced using a loop variable without or with a modifier to an environment variable as this would require the usage of delayed expansion as explained by help of command SET output on running in a command prompt window
set /?.For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?echo /?for /?popd /?pushd /?See also DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/.
The second batch file code in question does not work because of not using delayed expansion or avoiding the usage of environment variables defined/modified inside a command block and referenced within same command block using syntax
%variable%. The Windows command processorcmd.exeparses the entire command block from(of first FOR to matching)before executing the outer FOR the first time. See How does the Windows Command Interpreter (CMD.EXE) parse scripts? All%variable%references within this command block are replaced during this preprocessing phase already by current value of the referenced environment variable. So the code finally executed on iterating outer FOR does not contain anymore any%variable%environment variable reference as it can be seen on command lines output bycmd.exebefore executing the command line.