-1

I am trying to extract a substring in a for loop witin a batch script, but I'm missing something, as it will be delayed string inside the loop.

Below is the code: Please help how to do this:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
FOR /F "tokens=1* delims=" %%A IN ('dir /b /a-d') DO (      
        echo %%A
        set directory=%%A
        :: am calculating length here based on some logic, lets assume it as 2 
        set length=2
        set myvar = !directory:~0:length!
        echo !myvar!
    )
endlocal
pause

Output now

1.txt
ECHO is off.
2.txt
ECHO is off.
demo.cmd
ECHO is off.
Press any key to continue . . .

Expected output:

1.txt
1.
2.txt
2.
demo.cmd
de.
Press any key to continue . . .
Compo
  • 36,585
  • 5
  • 27
  • 39
  • 3
    Nest another `for` loop: `For %%G In (!length!) Do Set "myvar=!directory:~0,%%G!"` – Compo Jul 11 '21 at 15:55
  • 2
    The first problem is that you are searching for a solution for an [XY problem](https://xyproblem.info/). You better go back a step and let us know the directory names and which part of each directory name should be assigned to the environment variable `myvar`. I am pretty sure there is a much better method than whatever you use in your batch file. – Mofi Jul 11 '21 at 16:46
  • 2
    The second problem is that labels including invalid labels like `:: am calculating length here based on some logic, lets assume it as 2` cause an undefined behavior on batch file execution. Do not use `::` for comments. There is the command `rem` for comments which can be used also inside a command block starting with `(` and ending with matching `)`. – Mofi Jul 11 '21 at 16:48
  • 3
    The third problem is `set myvar = !directory:~0:length!` with two mistakes. The spaces around the equal sign must be removed. See [Why is no string output with 'echo %var%' after using 'set var = text' on command line?](https://stackoverflow.com/a/26388460/3074564) The other issue is using just the environment variable name `length` instead of referencing the value of the environment variable `length` which of course is not really possible because of delayed expansion is already used on environment variable `directory` and cannot be used for that reason for `length` defined above. – Mofi Jul 11 '21 at 16:52
  • 1
    [Compo](https://stackoverflow.com/users/6738015/compo) suggested a working workaround for this command line by assigning the current value of the environment variable `length` to a loop variable by using an additional `for` to be able to reference the length value in the delayed expanded string substitution. I recommend further to read the chapter **Issue 7: Usage of letters ADFNPSTXZadfnpstxz as loop variable** in [this answer](https://stackoverflow.com/a/60686543/3074564) and avoid in future using `A` as loop variable although `A` as used here is no problem. – Mofi Jul 11 '21 at 16:56
  • 2
    The fourth problem is using `dir /b /a-d` get a list of all __file__ names in __current__ directory and assigning the __file__ name to an environment variable named `directory`. Do you want to confuse yourself or just us? By the way: What should be the __current__ directory on running the batch file? The batch file does not contain any code to define the current directory. So if a user opens a command prompt window, runs `cd /D "%TEMP%"` and runs next `"C:\Full Path\BatchFile.cmd"`, the current directory would be the directory for temporary files. Is that really wanted by you? – Mofi Jul 11 '21 at 17:11
  • @Mofi thanks for all the pointers. I will surely incorporate al your suggestions. It is helpful to me as a new batch script developer. – hari krishna Jul 12 '21 at 06:30

1 Answers1

0

Leaving behind all the problems in the above script as pointed by @Mofi above. This issue can be solved by using the below to calculate the subsctring

For %%G In (!length!) Do Set "myvar=!directory:~0,%%G!"

Final script:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
FOR /F "tokens=1* delims=" %%A IN ('dir /b /a-d') DO (      
        echo %%A
        set directory=%%A
        
        set length=2
        set myvar = !directory:~0:length!
        For %%G In (!length!) Do Set "myvar=!directory:~0,%%G!"
        echo !myvar!
    )
endlocal
pause
  • 1
    Whilst I'm happy to have provided you with the solution to your issue, I'd still like to know why you are doing this. It does not make sense, because you clearly already know the length value in advance. If you know it in advance then you should be using `Set "length=2"` before the `For /F` loop, not within it. Then you would have been OK using `Set "myvar=!directory:~0,%length%!"` without any problems. Also, instead of simply copying my solution and inserting it, you should have at least removed the line it was a replacing, and followed the advice of @Mofi, to fix the other potential issues. – Compo Jul 12 '21 at 10:06
  • @compo , Thanks for the guidance. Yes you are right. My scenario quite complicated. Am not executing 'dir /b /a-d' at all but some other internal tool command. Only to provide a simple executable script i created this. But yeah , i will incorporate all yours and mofi 's suggestions in my final code – hari krishna Jul 13 '21 at 05:04