A relatively unknown feature of the windows shell (cmd.exe) is that it has a built in substring function. You can use the :~ operator in conjunction with any variable to obtain a substring of that variable. For example:
set foo=foobar
echo %foo:~3%
The above will output bar. You can also use two comma separated parameters if you want. The first one is the start index, and the second one is length:
echo %foo:~1,2%
This will display oo. You can also have a negative offset, but not the length:
echo %foo:~-3,3%
This will also produce bar. What would be a practical application for this? You tell me – there are hundreds of ways you could exploit this feature to your advantage. I personally use it in my scripts to create dated directories. Sometimes you want to create a folder labeled with the current date. The easy way to do this of course is:
mkdir "%date%"
The only problem is that this method doesn’t work. Because by default dates contain slashes (“/”) which are interpreted as path delimiters by the mkdir command. What you end up with is a directory tree:
Fri 10\27\2006\
This might be useful, but not exactly what we have wanted. What I really meant to do was this:
mkdir "%date:~0,3% %date:~4,2%-%date:~7,2%-%date:~-4,4%"
Yes, the line is much more verbose, but the end effect is well worth it – you end up with a neatly named folder Fri 10-27-2006. This is really useful trick for quick backup scripts and etc…
[tags]batch, cmd, windows, cmd.exe, shell, scripting, substring[/tags]
Substrings all very well on %VARIABLES%, but how do you take a substring of a FOR variable in a batch file? For example, the following code fails because the substring notation on “%%F” is not correct:
FOR /F %%F IN ("%FILELIST%") DO (
IF "%%F:~-10,-3%" == "%KEYWORD%" (
:: Process one way...
) ELSE (
:: Process another way...
)
)
How do you perform a substring operation on a FOR loop variable?
Here is what I did to get the FOR variable:
SETLOCAL EnableDelayedExpansion
FOR /F %%F IN ("%FILELIST%") DO (
SET G=%%F
IF "!G:~-10,-3!" == "%KEYWORD%" (
:: Process one way...
) ELSE (
:: Process another way...
)
)
The EnableDelayedExpansion switch allows us to use variables in a loop with the ! syntax instead of the % syntax.
Thank you Schmalls. That EnableDelayedExpansion was just what I needed to trim 17 leading characters (of file path) out of a string.
This is great stuff and exactly what I was looking for. I’ve been writing batch files for many years and never knew about this functionality. Thanks so must for posting it.
Thank you very much for the post!
And yet another thank-you – EnableDelayedExpansion just saved me hours of work!
Awesome posts, thanks! Found it via Google after looking up “batch file sub string”. I didn’t realize that the windows shell had a built in substring function until I stumbled onto this page.
Thanks again.
Hi all,
I need ur help. Actually I m trying to read 1 text file and trying to get the substring from that.
my test.txt file c0ntatins
BBB2100BBB
my requirement to get the value 2100. Means the value between the BBB and BBB.
Please give me some solution asap.
Thanks in advance.
@ Harish:
set test=BBB2100BBB
echo %test:~3,4%
@ Schmalls:
Thank you so much for this!