Page 1 of 1

String concatenation and arithmetic

Posted: 05 Apr 2011 11:03
by slimsamu
Hello,

For starters, I'm somewhat of a newbie when it comes to DOS Batch (CMD) language. I've started to write a small batch program which will be used to build a list of hosts, and a total number of CPUs requested (I hope to store these two items in separate variables).

The batch program can expect to always find a variable in the environment where it is executed of the form:

HOSTLIST=<nodename0> <number of CPUs><nodename1> <number of CPUs> ... <nodenameN><number of CPUs>

For example:

HOSTLIST=host000 20 host001 20 host002 20

What I would like to extract from this list is:

HOSTS=host000 host001 host002
CPUS=60 (this is the sum of 20+20+20)

I've written a few lines to calculate the CPUS value, but I quickly realized that this was not working properly (when number of CPUs > 9):

@ECHO OFF
set HOSTLIST=host000 2 host001 3

SET CPUS=0
SET HOSTS=
FOR %%j IN (%HOSTLIST%) DO (
FOR %%f IN (0 1 2 3 4 5 6 7 8 9) DO (
IF %%j==%%f SET /A CPUS=CPUS+%%j
)
)

echo CPUS=%CPUS%

Note that above I did not even start to explore building the HOSTLIST. So what I need to understand is how I can step through the the HOSTLIST and determine if a value is numeric or not. If yes, then it needs to be added to a running total, if not, it needs to be added to a list of hosts (concatenated).

I've looked at the article: viewtopic.php?f=3&t=193 but it does not appear to work as expected for this case.

Any pointers would be greatly appreciated.

Re: String concatenation and arithmetic

Posted: 05 Apr 2011 11:35
by aGerman
That means each second value (separated by spaces) is a number of CPUs?

Code: Select all

@echo off
set "HOSTLIST=host000 2 host001 3 host002 10"

set "HOSTS="
set "CPUS=0"
set "i=0"

setlocal enabledelayedexpansion
for %%a in (%HOSTLIST%) do (
  set /a i+=1
  set /a n=!i! %% 2
  if !n!==1 (
    set "HOSTS=!HOSTS! %%a"
  ) else (
    set /a CPUS+=%%a
  )
)

endlocal &set "HOSTS=%HOSTS:~1%" &set "CPUS=%CPUS%"

echo HOSTS=%HOSTS%
echo CPUS=%CPUS%
pause


Regards
aGerman

Re: String concatenation and arithmetic

Posted: 05 Apr 2011 11:57
by !k
Or

Code: Select all

@echo off
set "HOSTLIST=host000 2 host001 3 host002 10"

set "HOSTS="
set "CPUS=0"

setlocal enabledelayedexpansion
for %%a in (%HOSTLIST%) do (
  set "i=%%a"
  if /i "!i:~0,4!"=="host" (
    set "HOSTS=!HOSTS! %%a"
  ) else (
    set /a CPUS+=%%a
  )
)

endlocal &set "HOSTS=%HOSTS:~1%" &set "CPUS=%CPUS%"

echo HOSTS=%HOSTS%
echo CPUS=%CPUS%
pause

Re: String concatenation and arithmetic

Posted: 05 Apr 2011 19:55
by slimsamu
Thank you for the example scripts. I've incorporated this into a broader batch file and it works like a charm!!! Many thanks again for the rapid and accurate response.

Re: String concatenation and arithmetic

Posted: 05 Apr 2011 20:07
by ghostmachine4
the first big mistake you make is to use batch for string/text processing and arithmetic. Batch (cmd.exe) has only rudimentary string processing capabilities and fails when you want to do floating point maths. (eg 1 + 2.4). I can say that for 99.999999% of the time, your system should have vbscript (or powershell), so make full use of it for your scripting needs. Here's a vbscript demo.

Code: Select all

input = Split( WScript.Arguments(0) )
cpu=0
Dim hosts()
j=0
For i=0 To UBound(input)
   If i Mod 2 <> 0 Then
      cpu = cpu + input(i)   
   Else
      ReDim Preserve hosts(j)   
      hosts(j) = input(i)   
      j=j+1   
   End If   
Next


how to run it

Code: Select all


C:\work>cscript //nologo test1.vbs "host1 20 host2 31"
Cpu: 51
Host: host1
Host: host2


all the hosts are stored in array, and all the CPU values are summed up as it goes over the words. Of course, this could also be done (more compactly) with regular expression , which vbscript also supports, but that's another story for next time.