8
votes

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.

5

5 Answers

8
votes

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%
5
votes
@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
1
votes

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.

0
votes

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 (
0
votes

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