8

In a batch file, how can I get the last token in a variable regardless of whether it is a number or a word and regardless of how many tokens/words there are in the variable.

I will be passing an argument into the batch file like this:

C:\execbatch.bat "This is example one" or C:\execbatch.bat "This is example number 2"

And then the batch file will be like this:

@echo off

SET var=%1
SET last=some command to grab the last token of %var%
echo %last%
exit

Essentially, I need to be able to always grab the last token, in these examples, I would want to grab one from example 1 and 2 from example 2.

ADDITIONAL INFORMATION:

It is not the command line arguments that are the issue, that was just a simplified example:

The case is that I am calling a command inside of a batch file and sending its output to a variable like so:

C:\execbatch.bat memory or C:\execbatch.bat cpu

And then in the batch file:

For /F "Tokens=*" %%I in ('c:\monitor.exe -C custom_performance_counter -t %1 -w 80 -c 90') Do Set COMMANDOUTPUT=%%I

Echo %COMMANDOUTPUT%
Set CURRENTVALUE=some command to grab the last token of %COMMANDOUTPUT%
Echo "The current value is %CURRENTVALUE%"

This will output various results depending on the check type; however in every case the last token/variable is always the current value albeit either number or word.

Eli
  • 716
  • 1
  • 6
  • 12

5 Answers5

9

Why so complicated?

Solution for a string in a variable:

set var1=This is a String
for %%A in (%var1%) do set last=%%A

echo last=%last%

Solution for the result of an external command:

set xcmd=c:\monitor.exe -C custom_performance_counter -t %1 -w 80 -c 90
for /f "tokens=*" %%I in ('%xcmd%') do for %%A in (%%~I) do set last=%%A
echo last=%last%
foo2
  • 111
  • 1
  • 2
7
@echo off

set var1=This is a String
set var2=%var1%
set i=0

:loopprocess
for /F "tokens=1*" %%A in ( "%var1%" ) do (
  set /A i+=1
  set var1=%%B
  goto loopprocess )

echo The string contains %i% tokens.

for /F "tokens=%i%" %%G in ( "%var2%" ) do set last=%%G

echo %last%

pause
Eli
  • 716
  • 1
  • 6
  • 12
  • This works brilliantly, especially if you need a non-space token delimiter e.g "tokens=1* delims=." will spilt on periods not spaces. – Grhm Feb 16 '16 at 16:28
1

If you insist on passing only a single argument, then you can use a subroutine:

@echo off
call :get_last %~1
echo.%last%
goto :eof

rem get_last tokens...
:get_last
  set last=%1
  shift
  if [%1]==[] goto :eof
  goto get_last

However, if you're just passing any number of arguments to the batch, then you can do that directly:

@echo off
:l
set last=%1
shift
if [%1]==[] goto pl
goto l
:pl
echo %last%

Side note: You rarely want to put exit in a batch file, as it exits the command processor, not the batch. That's kinda annoying if you use it directly from the shell or from other batch files.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • I'm sorry, it would appear I simplified my situation a little too much. I have edited my post with more detail on the situation. – Eli Mar 29 '11 at 14:50
  • @Eli, you should be able to use the subroutine just fine in that case too. Just use `call :get_last %COMMANDOUTPUT%` or stick that directly into the `for`. – Joey Mar 29 '11 at 14:53
  • +1, But perhaps the quotes have to be removed before the call, as the samples suggest this – jeb Mar 29 '11 at 15:31
  • @jeb: I'd be surprised if that tool outputs everything within quotes. But if it does that's trivial to resolve with substring or a one-line subroutine. – Joey Mar 29 '11 at 15:44
  • I couldn't get that to work; however, I did finally find a working solution. – Eli Mar 30 '11 at 00:24
0

Some code golf on Eli's answer.

@echo off

set var1=This is a String
REM token_string will be manipulated each loop
set token_string=%var1%

:find_last_loop
for /F "tokens=1*" %%A in ( "%token_string%" ) do (
  set last=%%A
  set token_string=%%B
  goto find_last_loop)

echo %last%

pause

And to find something with ':' delimiters...

for /F "tokens=1* delims=:" %%A in ( "%token_string%" ) do (
gjcamann
  • 621
  • 4
  • 14
0

if the tokens are separated by spaces, the last token is:

set b=command to grab the last token
for %i in (%b: =\%) do echo %~ni
Zimba
  • 2,854
  • 18
  • 26