Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LastIndexOf in Windows batch

I need to implement a function in a Windows batch script to get the LastIndexOf a character into a given string.

For example: Given the following string, I need to get the last index of character '/':

/name1/name2/name3
            ^

So I need to get the value:

12
like image 724
Daniel Peñalba Avatar asked Oct 22 '12 10:10

Daniel Peñalba


2 Answers

Joey's solution works, but the character to find is hard coded, and it is relatively slow.

Here is a parametized function that is fast and can find any character (except nul) within the string. I pass the name of variables containing the string and the character instead of string literals so that the function easily supports all characters.

@echo off
setlocal

set "test=/name1/name2/name3"
set "char=/"

::1st test simply prints the result
call :lastIndexOf test char

::2nd test stores the result in a variable
call :lastIndexOf test char rtn
echo rtn=%rtn%

exit /b

:lastIndexOf  strVar  charVar  [rtnVar]
  setlocal enableDelayedExpansion

  :: Get the string values
  set "lastIndexOf.char=!%~2!"
  set "str=!%~1!"
  set "chr=!lastIndexOf.char:~0,1!"

  :: Determine the length of str - adapted from function found at:
  :: http://www.dostips.com/DtCodeCmdLib.php#Function.strLen
  set "str2=.!str!"
  set "len=0"
  for /L %%A in (12,-1,0) do (
    set /a "len|=1<<%%A"
    for %%B in (!len!) do if "!str2:~%%B,1!"=="" set /a "len&=~1<<%%A"
  )

  :: Find the last occurrance of chr in str
  for /l %%N in (%len% -1 0) do if "!str:~%%N,1!" equ "!chr!" (
    set rtn=%%N
    goto :break
  )
  set rtn=-1

  :break - Return the result if 3rd arg specified, else print the result
  ( endlocal
    if "%~3" neq "" (set %~3=%rtn%) else echo %rtn%
  )
exit /b

It wouldn't take much modification to create a more generic :indexOf function that takes an additional argument specifying which occurance to find. A negative number could specify to search in reverse. So 1 could be the 1st, 2 the 2nd, -1 the last, -2 penultimate, etc.

like image 184
dbenham Avatar answered Sep 28 '22 07:09

dbenham


(Note: I'm assuming Windows batch files because, frankly, I have only seen a single question asking for an actual DOS batch file here so far. Most people simply misattribute “DOS” to anything that has a window of gray-on-black monospaced text without knowing what they're actually talking of.)

Just loop through it, updating the index as you go:

@echo off
setlocal enabledelayedexpansion
set S=/name1/name2/name3
set I=0
set L=-1
:l
if "!S:~%I%,1!"=="" goto ld
if "!S:~%I%,1!"=="/" set L=%I%
set /a I+=1
goto l
:ld
echo %L%
like image 41
Joey Avatar answered Sep 28 '22 06:09

Joey