49

Suppose I have a value such as "Abc_123" that's stored in a variable in a batch (cmd) file. I want to end up with a variable that contains only "123". Is there any built-in way to do this?

I'm not terribly picky about the method, or performance, as long as it's built in to a typical Windows (Vista/2008) system.

0

6 Answers 6

61

Use the substring syntax:

C:\Users\John>set string=Abc_123

C:\Users\John>echo %string%
Abc_123

C:\Users\John>echo %string:~4,3%
123
5
  • 6
    You can see the full syntax with help set as mentioned in What is the best way to do a substring in a batch file? on StackOverflow. Commented Oct 25, 2016 at 22:49
  • 5
    If I needed that 4 and 3 to be variable inputs, how would I do that? %string:~%start%,%len%% Commented Nov 18, 2017 at 19:06
  • 2
    never mind. I found the answer. ss64.com/nt/syntax-substring.html Commented Nov 18, 2017 at 19:27
  • 3
    To summarize the link from @MakPo: use CALL, like CALL SET _substring=%%_donor:~%_startchar%,%_length%%% Commented Feb 4, 2019 at 13:10
  • @ToMakPo The CALL solution is essential. i struggled til i found that, thx to you! Should be part of an answer. Commented Nov 20, 2021 at 17:44
17

If you just want everything after the underscore (and do not necessarily know the length of the string or where the underscore is, but can rely on there being only one underscore), try:

for /f "tokens=2 delims=_" %%a in ("%STRING%") do (
  set AFTER_UNDERSCORE=%%a
)

Basically, your string will be split into tokens using the underscore as a delimiter (delims=_). Only the second one (tokens=2) will be passed (as variable %%a) to the for loop. The loop will only run once since you are dealing with a single string in this case.

If you want to save the stuff both before and after the underscore, try:

for /f "tokens=1,2 delims=_" %%a in ("%STRING%") do (
  set BEFORE_UNDERSCORE=%%a
  set AFTER_UNDERSCORE=%%b
)

Note that %%a is the variable for the first token of the split; %%b is the variable for the second token of the split.

9
set var1=Abc_123
set var2=%var1:*_=%
echo %var2%
13
  • 5
    What does this do specifically? Commented Oct 29, 2019 at 17:09
  • Oh, if you were asking how this code works: it removes everything before the number, preceded by an underscore. Commented Nov 23, 2019 at 13:31
  • @Zimba is there a way to simply extend this to "last _"? Also where can I find this in any documentation? Commented Jan 25, 2020 at 0:40
  • 1
    @TWiStErRob: I see. If you don't know how many _ there are, then loop to the last one, then set var Commented Jan 29, 2020 at 16:24
  • 2
    You mean to be left with Abc_, like a head function? Commented Jun 25, 2021 at 17:24
2

This will extract last token from string with any tokens number and any type of delimiters. In this example ECHO will show "i". Although it requires a loop function, it's very fast.

@echo off
set "Var=a_b_c_d_e_f_g_h_i"
call :LoopLastToken "%Var%"
echo "%Var%"
pause
exit

:LoopLastToken
    set "Var=%~1"
    if not "%Var:*_=%"=="%~1" (
    call :LoopLastToken "%Var:*_=%")
exit /b
0

If you find that the batch language isn't powerful enough to do what you want - and it likely won't take you too long to get to that point - you can use the Windows PowerShell. This isn't installed by default on all versions of Windows, but you can download it free of charge.

If you don't like the PowerShell language, there's Perl. You'll have to install that on all systems though. There are others too.

2
  • 3
    The question is not asking about Powershell or Perl Commented Oct 29, 2019 at 13:31
  • 2
    Powershell requires (much) more resources (RAM) than cmd so if all you need is something quick and simple, it makes more sense to use cmd. CMD uses native Win32 calls and Powershell uses the .Net framework. Powershell takes longer to load, and can consume a lot more RAM than CMD. "I monitored a Powershell session executing Get-ChildItem. It grew to 2.5GB (all of it private memory) after a few minutes and was no way nearly finished. CMD “dir /o-d” with a small scrollback buffer finished in about 2 minutes, and never took more than 300MB of memory." qr.ae/pGmwoe Commented Nov 20, 2021 at 17:52
0

If you need a batch substring implementation which is able to accept variables for start-of-string and length of string then I would suggest the following answer:

@echo off
set sLongString=Abc_123
set StartPos=4
set Len=3
call :Substring %sLongString% %StartPos% %Len% sSubStrResult
echo %sSubStrResult%

Output: 123

https://stackoverflow.com/a/77612600/9134997

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.