kozak
kozak

Reputation: 1

How to extract each value from delimited string in batch script and how to place labels for proper flow

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

Answers (2)

Compo
Compo

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

SomethingDark
SomethingDark

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

Related Questions