Search code examples
stringvariablesbatch-filesubstringstring-length

Batch file getting a substring from a string from a position to a length


(Edited at 04.03.2015) This is the working corrected version of the code. The aim of this code is to get paths of some directories and subdirectories of which structure shown below, to make a list.

C:\__Genus1\_Species1\Directories

C:\__Genus1\Directories

C:\Directories

C:\_Family\Directories

C:\_Family\__Genus1\_Species1\Directories

@ECHO off
setlocal enabledelayedexpansion
SET "_sDr="
SET "_sPt0="
SET "_sPt1="
SET "_sPt2="
SET "_sPt1st="
SET "_sPt2nd="
SET "_sDirYo="
SET "_sDirMo="
SET "_iLengthDir="
SET "_iFound1="
SET "_iFound2="
SET "_stri="
SET "_cBckslsh="
SET "_iStart="
SET "_cTab= "
FOR /d %%a IN (*) DO (
    SET "_sDr=%%a"
    SET "_sPt0=!_sDr:~0,1!"
    SET "_sPt1=!_sDr:~1,1!"
    SET "_sPt2=!_sDr:~2,1!"
    SET "_sPt1st=%%~dpa"
    IF "!_sPt0!"=="[" (
        ECHO 1. %%a>>List.txt
    ) ELSE IF "!_sPt2!"=="_" (
        ECHO 2. %%a>>List.txt
    ) ELSE IF "!_sPt1!"=="_" (
        FOR /d %%a IN (!_sPt1st!!_sDr!\*) DO (
            SET "_sPt2nd=%%a"
            SET "_cBckslsh=\"
            SET "_iStart=3"
            CALL :instrc !_sPt2nd!, !_cBckslsh!, !_iStart!
            SET "_iFound1=!_resulti!"
            SET /A _iLengthDir=!_iFound1!-!_iStart!
            CALL :substr !_sPt2nd!, !_iStart!, !_iLengthDir!
            SET "_sDirYo=!_results:~2!"
            SET "_sDirYo=!_sDirYo:_= !"
            SET /A _iFound1=!_iFound1!+1
            CALL :instrc !_sPt2nd!, !_cBckslsh!, !_iFound1!
            SET "_iFound2=!_resulti!"
            SET /A _iLengthDir=!_iFound2!-!_iFound1!
            CALL :substr !_sPt2nd!, !_iFound1!, !_iLengthDir!
            SET "_sDirMo=!_results!"
            SET "_sDirMo=!_sDirMo:_= !"
            ECHO !_sDirYo!%_cTab%!_sDirMo!>>List.txt
        )
    ) ELSE IF "!_sPt0!"=="_" (
        ECHO 4. %%a>>List.txt
    ) ELSE (
        ECHO NA!_cTab!!_sDr:_= !>>List.txt
    )
)
goto :eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::Function name: instrc                                          ::
::_resulti: returns the position of a character in a string      ::
::parameters:                                                    ::
::_sStringfi: a string which a caharacter will be found in it    ::
::_cToBeFoundfi: a caharacter of which position will be found    ::
::_iStartfi: position at which to start looking for _cToBeFoundfi::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:instrc
SETLOCAL
SET "_sStringfi=%1"
SET "_cToBeFoundfi=%2"
SET "_iStartfi=%3"
SET "_iLocAc="
SET "_cLocAc="
FOR /L %%a IN (%_iStartfi%,1,255) DO (
    SET "_iLocAc=%%a"
    SET "_cLocAc=!_sStringfi:~%%a,1!"
    IF "!_cLocAc!"=="!_cToBeFoundfi!" GOTO ENDF
)
:ENDF
ENDLOCAL & SET "_resulti=%_iLocAc%"

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::Function name: substr                                                ::
::_results: returns a substring of a string, of which start point      ::
::and length given                                                     ::
::parameters:                                                          ::
::_sStringfs: a string which a substringwill be taken from it          ::
::_iStartfs: an integer value for starting position                    ::
::_iLengthfs: an integer value for length of substring                 ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:substr
setlocal
set "_sStringfs=%1"
set "_iStartfs=%2"
set "_iLengthfs=%3"
set "_substr_res=!_sStringfs:~%_iStartfs%,%_iLengthfs%!"
endlocal & set "_results=%_substr_res%"

Solution

  • You are not so far:

    @ECHO off
    setlocal enabledelayedexpansion
    SET "_string=abcdefghij"
    SET "_length=3"
    SET "_substr="
    
    REM See below:
    SET "_substr=!_string:~4,%_length%!"
    
    ECHO !_substr!
    

    For your original code, you could use another function to do this. Instead of:

    SET /A _ptkYou=!_ptke!-24
    ::::Here is the original problem::::
    SET "_ptkYo=!_ptkY!:~24,!_ptkYou!"
    ECHO !_ptkYo!>>Liste.txt
    

    Use:

    CALL :substr !_ptkY!, !_ptkYou!
    SET "_ptkYo=!_result2!"
    ECHO !_ptkYo!>>Liste.txt
    

    Then add the following at the end:

    :substr
    setlocal
    set "_a=%1"
    set "_b=%2"
    set "_substr_res=!_a:~4,%_b%!"
    endlocal & set "_result2=%_substr_res%"