Reputation: 1
I want to extract folder name from a path stored in a variable. I want each folder name to be extracted and stored in separate variable. I tried the below code and got the output but the output is not as desired. I only want one cycle of output. Also I want to understand how to place labels in batch files. I'm finding difficulties in this.
Query1
set MYDIR=C:\FOLDER1\FOLDER2\FOLDER2
call :parse "%MYDIR%"
:parse
setlocal
set MYDIRS=%1
set MYDIRS=%MYDIRS:"=%
FOR /f "tokens=1* delims=\" %%a IN ("%MYDIRS%") DO (
if not "%%a" == "" call :sub %%a
if not "%%b" == "" call :parse "%%b"
)
:sub
@echo Subfolder extracted=^%1
Output
Subfolder extracted= C:
Subfolder extracted= FOLDER1
Subfolder extracted= FOLDER2
Subfolder extracted= FOLDER3
Subfolder extracted= C:
Subfolder extracted= FOLDER1
Subfolder extracted= FOLDER2
Subfolder extracted= FOLDER3
Query2
Also when i use a label to check if my string is empty and if uts empty it should go to the :eof however it goes to eof even when the MYDIR is not empty
set MYDIR=C:\FOLDER1\FOLDER2\FOLDER2
if "%MYDIR%" == "" goto :err_emptyFile
:err_emptyFile
@echo File path is empty
goto :eof
call :parse "%MYDIR%"
:parse
setlocal
set MYDIRS=%1
set MYDIRS=%MYDIRS:"=%
FOR /f "tokens=1* delims=\" %%a IN ("%MYDIRS%") DO (
if not "%%a" == "" call :sub %%a
if not "%%b" == "" call :parse "%%b"
)
:sub
@echo Subfolder extracted=^%1
:eof
@echo :eof
@echo file path is empty
output
File path is empty
:eof
File path is empty
Subfolder extracted= C:
Subfolder extracted= FOLDER1
Subfolder extracted= FOLDER2
Subfolder extracted= FOLDER3
Subfolder extracted= C:
Subfolder extracted= FOLDER1
Subfolder extracted= FOLDER2
Subfolder extracted= FOLDER3
Upvotes: 0
Views: 300
Reputation: 38589
Here's an alternative idea, you may find interesting:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "MYDIR=C:\FOLDER1\FOLDER2\FOLDER3"
Set "MYDIR=%MYDIR:^=^^%"
Set "MYDIR=%MYDIR:!=^!%"
For /F "Delims==" %%G In ('"(Set LEVEL[) 2>NUL"') Do Set "%%G="
Set "i=1"
SetLocal EnableDelayedExpansion
Set "LEVEL[!i!]=%MYDIR:\=" & Set /A i += 1 & Set "LEVEL[!i!]=%"
If "%LEVEL[1]:~-1%" == ":" Set "LEVEL[1]=%LEVEL[1]%\"
(Set LEVEL[) 2>NUL
For /F "Tokens=1,2" %%G In ("!CMDCMDLINE!") Do (Endlocal
If /I "%%~nG" == "CMD" If /I "%%~H" == "/C" Pause)
Upvotes: 0
Reputation: 14305
Scripts run top-down one line at a time until they encounter a goto
, encounter a call
, get told to stop with an exit
, or they run out of code to run.
Labels are just that - labels. All they do is indicate a specific place in the script; there's nothing about them that keeps the script from entering the new section marked by the label.
Because your first snippet doesn't change the flow of the code after the for
loop, the code continues down, one line at a time, until it reaches :sub
. Since there's nothing preventing your code from entering the :sub
section, it continues on and runs once more with whatever variables happen to be currently set in memory.
Similarly, your second snippet does nothing to stop your code from just immediately entering :err_emptyFile
.
On a somewhat related note, :eof
is already a built-in label that you can imagine as being the very last line in the script. Please don't create an actual label called :eof
, as this could have unintended consequences.
Subroutines are essentially tiny batch scripts embedded in your main script, and they also don't stop until you tell them to with either a goto :eof
or an exit /b
(or if they're the very last part of your script and you run out of code to execute).
With all this in mind, your script will run properly if you tell the code to stop at the right places:
@echo off
set MYDIR=C:\FOLDER1\FOLDER2\FOLDER3
if "%MYDIR%" == "" (
echo File path is empty
goto :eof
)
call :parse "%MYDIR%"
exit /b
:parse
setlocal
set MYDIRS=%1
set MYDIRS=%MYDIRS:"=%
FOR /f "tokens=1* delims=\" %%a IN ("%MYDIRS%") DO (
if not "%%a" == "" call :sub %%a
if not "%%b" == "" call :parse "%%b"
)
exit /b
:sub
echo Subfolder extracted=^%1
Upvotes: 1