How to get the length of a string in a batch file?

There seems to be no easy way to get the length of a string in a batch file. For example.

SET MY_STRING=abcdefg SET /A MY_STRING_LEN=??? 

How would I find the string length MY_STRING ?

Bonus points, if the string length function processes all possible characters in strings, including escape characters, for example: !%^^()^! .

+62
string windows batch-file
Apr 29 2018-11-21T00:
source share
14 answers

Since there is no built-in function for the length of the string, you can write your own function, for example, this:

 @echo off setlocal REM *** Some tests, to check the functionality *** REM *** An emptyStr has the length 0 set "emptyString=" call :strlen result emptyString echo %result% REM *** This string has the length 14 set "myString=abcdef!%%^^()^!" call :strlen result myString echo %result% REM *** This string has the maximum length of 8191 setlocal EnableDelayedExpansion set "long=." FOR /L %%n in (1 1 13) DO set "long=!long:~-4000!!long:~-4000!" (set^ longString=!long!!long:~-191!) call :strlen result longString echo %result% goto :eof REM ********* function ***************************** :strlen <resultVar> <stringVar> ( setlocal EnableDelayedExpansion (set^ tmp=!%~2!) if defined tmp ( set "len=1" for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( if "!tmp:~%%P,1!" NEQ "" ( set /a "len+=%%P" set "tmp=!tmp:~%%P!" ) ) ) ELSE ( set len=0 ) ) ( endlocal set "%~1=%len%" exit /b ) 

This function always requires 13 loops instead of the simple strlen function, which requires strlen loops.
It processes all characters.

A strange expression (set^ tmp=!%~2!) necessary for processing extra-long strings, otherwise they cannot be copied.

+82
Apr 30 '11 at 12:01
source share

You can do this in two lines, completely in a batch file, by writing a line to a file and then getting the length of the file. You just need to subtract two bytes to account for the automatic addition of CR + LF to the end.

Let's say your line is in a variable called strvar :

 ECHO %strvar%> tempfile.txt FOR %%? IN (tempfile.txt) DO ( SET /A strlength=%%~z? - 2 ) 

The length of the string is now in a variable called strlength .

A bit more detailed:

  • FOR %%? IN (filename) DO ( ... FOR %%? IN (filename) DO ( ... : retrieves file information
  • SET /A [variable]=[expression] : evaluate expression numerically
  • %%~z? : special expression for getting file length

To sing the whole team in one line:

 ECHO %strvar%>x&FOR %%? IN (x) DO SET /A strlength=%%~z? - 2&del x 
+31
Dec 19 '11 at 18:54
source share

I prefer the accepted jeb answer is the fastest solution and the one that I use in my own scripts. (There are actually a few additional optimizations in DosTips, but I don't think they are worth it)

But it's time to come up with new efficient algorithms. Here is a new algorithm that uses the FINDSTR / O option:

 @echo off setlocal set "test=Hello world!" :: Echo the length of TEST call :strLen test :: Store the length of TEST in LEN call :strLen test len echo len=%len% exit /b :strLen strVar [rtnVar] setlocal disableDelayedExpansion set len=0 if defined %~1 for /f "delims=:" %%N in ( '"(cmd /v:on /c echo(!%~1!&echo()|findstr /o ^^"' ) do set /a "len=%%N-3" endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len% exit /b 

The code subtracts 3 because the parser juggles the command and adds a space before executing CMD / V / C. This can be prevented by using (echo(!%~1!^^^) .




For those who want to get the maximum maximum performance, jeb's answer can be accepted for use as a batch "macro" with arguments . This is an advanced batch technique developed by DosTips that eliminates the essentially slow process of the CALLing a: routine. You can get more information about the concepts of batch macros here , but this link uses a more primitive, less desirable syntax.

The following is an optimized @strLen macro with examples showing the differences between using the macro and: routines, as well as differences in performance.

 @echo off setlocal disableDelayedExpansion :: -------- Begin macro definitions ---------- set ^"LF=^ %= This creates a variable containing a single linefeed (0x0A) character =% ^" :: Define %\n% to effectively issue a newline with line continuation set ^"\n=^^^%LF%%LF%^%LF%%LF%^^" :: @strLen StrVar [RtnVar] :: :: Computes the length of string in variable StrVar :: and stores the result in variable RtnVar. :: If RtnVar is is not specified, then prints the length to stdout. :: set @strLen=for %%. in (1 2) do if %%.==2 (%\n% for /f "tokens=1,2 delims=, " %%1 in ("!argv!") do ( endlocal%\n% set "s=A!%%~1!"%\n% set "len=0"%\n% for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (%\n% if "!s:~%%P,1!" neq "" (%\n% set /a "len+=%%P"%\n% set "s=!s:~%%P!"%\n% )%\n% )%\n% for %%V in (!len!) do endlocal^&if "%%~2" neq "" (set "%%~2=%%V") else echo %%V%\n% )%\n% ) else setlocal enableDelayedExpansion^&setlocal^&set argv=, :: -------- End macro definitions ---------- :: Print out definition of macro set @strLen :: Demonstrate usage set "testString=this has a length of 23" echo( echo Testing %%@strLen%% testString %@strLen% testString echo( echo Testing call :strLen testString call :strLen testString echo( echo Testing %%@strLen%% testString rtn set "rtn=" %@strLen% testString rtn echo rtn=%rtn% echo( echo Testing call :strLen testString rtn set "rtn=" call :strLen testString rtn echo rtn=%rtn% echo( echo Measuring %%@strLen%% time: set "t0=%time%" for /l %%N in (1 1 1000) do %@strlen% testString testLength set "t1=%time%" call :printTime echo( echo Measuring CALL :strLen time: set "t0=%time%" for /l %%N in (1 1 1000) do call :strLen testString testLength set "t1=%time%" call :printTime exit /b :strlen StrVar [RtnVar] :: :: Computes the length of string in variable StrVar :: and stores the result in variable RtnVar. :: If RtnVar is is not specified, then prints the length to stdout. :: ( setlocal EnableDelayedExpansion set "s=A!%~1!" set "len=0" for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( if "!s:~%%P,1!" neq "" ( set /a "len+=%%P" set "s=!s:~%%P!" ) ) ) ( endlocal if "%~2" equ "" (echo %len%) else set "%~2=%len%" exit /b ) :printTime setlocal for /f "tokens=1-4 delims=:.," %%a in ("%t0: =0%") do set /a "t0=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100 for /f "tokens=1-4 delims=:.," %%a in ("%t1: =0%") do set /a "t1=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100 set /a tm=t1-t0 if %tm% lss 0 set /a tm+=24*60*60*100 echo %tm:~0,-2%.%tm:~-2% msec exit /b 

- Sampling result -

 @strLen=for %. in (1 2) do if %.==2 ( for /f "tokens=1,2 delims=, " %1 in ("!argv!") do ( endlocal set "s=A!%~1!" set "len=0" for %P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( if "!s:~%P,1!" neq "" ( set /a "len+=%P" set "s=!s:~%P!" ) ) for %V in (!len!) do endlocal&if "%~2" neq "" (set "%~2=%V") else echo %V ) ) else setlocal enableDelayedExpansion&setlocal&set argv=, Testing %@strLen% testString 23 Testing call :strLen testString 23 Testing %@strLen% testString rtn rtn=23 Testing call :strLen testString rtn rtn=23 Measuring %@strLen% time: 1.93 msec Measuring CALL :strLen time: 7.08 msec 
+22
Dec 17 '12 at 23:44
source share

The first few lines just demonstrate the function: strLen.

 @echo off set "strToMeasure=This is a string" call :strLen strToMeasure strlen echo.String is %strlen% characters long exit /b :strLen setlocal enabledelayedexpansion :strLen_Loop if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop (endlocal & set %2=%len%) goto :eof 

Of course, this is not so effective in the "13 loop" version provided by jeb. But this is easier to understand, and your 3GHz computer can skip several thousand iterations in a fraction of a second.

+9
Jun 27 '13 at 20:52
source share

Yes, of course, there is an easy way using vbscript (or powershell).

 WScript.Echo Len( WScript.Arguments(0) ) 

save this as strlen.vbs and on the command line

 c:\test> cscript //nologo strlen.vbs "abcd" 

Use a for loop to capture the result (or use vbscript fully for your scripting task)

Of course, you need to create bulky workarounds using the package, and there is no excuse not to use it, since vbscript is available with every Windows distribution (and powershell in the future).

+5
Apr 30 2018-11-11T00:
source share

Just found a ULTIMATE solution:

 set "MYSTRING=abcdef!%%^^()^!" (echo "%MYSTRING%" & echo.) | findstr /O . | more +1 | (set /P RESULT= & call exit /B %%RESULT%%) set /A STRLENGTH=%ERRORLEVEL%-5 echo string "%MYSTRING%" length = %STRLENGTH% 

Output:

 string "abcdef!%^^()^!" length = 14 

It processes escape characters, an order of magnitude simpler than most of the solutions above, and does not contain loops, magic numbers, DelayedExpansion files, temp, etc.

If you use a script outside the package (for example, to enter commands manually), replace %%RESULT%% with %RESULT% .

If necessary, the %ERRORLEVEL% variable can be set to FALSE using any NOP command, for example. echo. >nul

+5
Feb 12 '17 at 13:41
source share

If you are using Windows Vista +, try this Powershell method:

 For /F %%L in ('Powershell $Env:MY_STRING.Length') do ( Set MY_STRING_LEN=%%L ) 

or alternatively:

 Powershell $Env:MY_STRING.Length > %Temp%\TmpFile.txt Set /p MY_STRING_LEN = < %Temp%\TmpFile.txt Del %Temp%\TmpFile.txt 

I am on Windows 7 x64 and this works for me.

+3
Mar 05 '14 at 7:45
source share

I like the two-line approach of jmh_gr.

It will not work with single digits unless you put () around part of the command before redirecting. since 1> - the special command "Echo is On" will be redirected to the file.

In this example, single digits should be considered, but not other special characters, such as < , that may be in the string.

 (ECHO %strvar%)> tempfile.txt 
+2
Sep 19 2018-12-12T00: 00Z
source share

Another batch of script to calculate the length of a string with just a few lines. It may not be the fastest, but it is quite small. The routine ": len" returns the length in the second parameter. The first parameter is the actual string being parsed. Please note: special characters must be escaped, that is, in the case of any line in the batch file.

 @echo off setlocal call :len "Sample text" a echo The string has %a% characters. endlocal goto :eof :len <string> <length_variable> - note: string must be quoted because it may have spaces setlocal enabledelayedexpansion&set l=0&set str=%~1 :len_loop set x=!str:~%l%,1!&if not defined x (endlocal&set "%~2=%l%"&goto :eof) set /al=%l%+1&goto :len_loop 
+1
Apr 09 '14 at 19:11
source share
 @echo off & setlocal EnableDelayedExpansion set Var=finding the length of strings for /l %%A in (0,1,10000) do if not "%Var%"=="!Var:~0,%%A!" (set /a Length+=1) else (echo !Length! & pause & exit /b) 

set var the way you want to find its length, or change it to set / p var = so that the user types it. Put it here for future reference.

+1
Jul 11 '15 at 18:03
source share
 @echo off :: warning doesn't like * ( in mystring setlocal enabledelayedexpansion set mystring=this is my string to be counted forty one call :getsize %mystring% echo count=%count% of "%mystring%" set mystring=this is my string to be counted call :getsize %mystring% echo count=%count% of "%mystring%" set mystring=this is my string call :getsize %mystring% echo count=%count% of "%mystring%" echo. pause goto :eof :: Get length of mystring line ######### subroutine getsize ######## :getsize set count=0 for /l %%n in (0,1,2000) do ( set chars= set chars=!mystring:~%%n! if defined chars set /a count+=1 ) goto :eof :: ############## end of subroutine getsize ######################## 
0
Apr 14 '15 at 9:50
source share

I want a preface to this, saying that I know little about writing code / script / etc. but thought that I would share a solution that seems to have come up with. Most of the answers here seemed to turn my head upside down, so I was curious to find out if what I wrote was comparable.

 @echo off set stringLength=0 call:stringEater "It counts most characters" echo %stringLength% echo.&pause&goto:eof :stringEater set var=%~1 :subString set n=%var:~0,1% if "%n%"=="" ( goto:eof ) else if "%n%"==" " ( set /a stringLength=%stringLength%+1 ) else ( set /a stringLength=%stringLength%+1 ) set var=%var:~1,1000% if "%var%"=="" ( goto:eof ) else ( goto subString ) goto:eof 
0
Jan 10 '17 at 11:13 on
source share

This is just Simplier !

A clean batch solution. No temporary files. There are no long scripts.

 @echo off setlocal enabledelayedexpansion set String=abcde12345 for /L %%x in (1,1,1000) do ( if "!String:~%%x!"=="" set Lenght=%%x & goto Result ) :Result echo Lenght: !Lenght! 

1000 is the maximum string length. Change it based on your needs.

0
Dec 04 '18 at 12:52
source share
 @ECHO OFF SET string= SET /A stringLength=0 :CheckNextLetter REM Subtract the first letter and count up until the string="". IF "%string%" NEQ "" ( SET string=%string:~1% SET /A stringLength=%stringLength%+1 GOTO :CheckNextLetter ) ELSE ( GOTO :TheEnd ) :TheEnd ECHO There is %stringLength% character^(s^) in the string. PAUSE 

This works for me. Hope this is helpful to someone else. No need to adjust to any length. I simply delete the first letter and compare with "" until the string becomes equal to "".

-one
May 03 '19 at 10:55
source share



All Articles