2

I'm trying to compare a sequence of 9 numbers (separated by ,) using a batch file. The comparison is always made by the corresponding sequence like:

mPrevious[0] <-> mCurrent[0]
mPrevious[1] <-> mCurrent[1]

I need to know if at least one sequece have changed. In the example bellow, 234 changed to 230 and 146 to 149.

The sketch I have so far is:

setlocal ENABLEDELAYEDEXPANSION
@echo off

set mPrevious=229,234,235,127,58,0,131,133,146
set mCurrent=229,230,235,127,58,0,131,133,149

for /f "tokens=1,2,3,4,5,6,7,8,9 delims=," %%a IN ('echo !mPrevious!') do (

)

The number of entries (currently 9) might change in the future. But for now they are just 9.

I'm not sure what is the proper way to do it inside a batch script.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Azevedo
  • 2,059
  • 6
  • 34
  • 52
  • If all you need to know is if the string has changed, you could perform a simple string comparison. `For /L %%i in (1,1,%Array.Index%) Do If not "!mPrevious[%%i]!" == "!mCurrent[%%i]!" Echo value changed in mCurrent [%%i]` – T3RR0R May 24 '20 at 00:05
  • @T3RR0R I'm confused. Obviously batch doesn't support arrays, so is `mPrevious[0]` ***really*** defined or is it pointing to the first item of `mPrevious`, like in other languages? – ScriptKidd May 24 '20 at 00:09
  • If you need to know which value in the list of the current array index has changed, you could loop over each value in both array Vars and use string substitution OR conditional tests to determine which values are different. – T3RR0R May 24 '20 at 00:09
  • @hackingAddict1337 Arrays may not be supported in Batch, however, they can be emulated. Search [Batch-Files] "Arrays" and you'll find many examples of "pseudo" Arrays, lists etc. Also the for /L loop in my initial comment should be adjusted to begin from 0 index – T3RR0R May 24 '20 at 00:11
  • [this](https://stackoverflow.com/q/10166386/12861751)? @OP has to transform `mPrevious` into array. in my opinion (off topic), there are much easier solutions (i'm thinking now) – ScriptKidd May 24 '20 at 00:33
  • 1
    *N. B.:* I wouldn't call this an array but a list... – aschipfl May 25 '20 at 19:14

3 Answers3

3
@echo off 

title <nul && title ...\%~nx0
setlocal enabledelayedexpansion

set "_mPrevious=229,234,235,127,58,0,131,133,146"
set "_mCurrents=229,230,235,127,58,0,131,133,149"

echo/!_mPrevious!|find "!_mCurrents!" >nul && (
   endlocal & echo\Nothing changed^!! & goto :EOF )

for %%i in (!_mPrevious!)do set /a "_i+=1+0" && call set "_mPrev_!_i!=%%~i"
for %%j in (!_mCurrents!)do set /a "_j+=1+0" && call set "_mCurr_!_j!=%%~j"

if !_i! neq !_j! endlocal & echo\Varyables have different lengths^!! & goto :EOF

for /L %%L in (1 1 !_j!)do if !_mPrev_%%~L! neq !_mCurr_%%~L! echo\!_mPrev_%%~L! updated to: !_mCurr_%%~L!

endlocal && goto :EOF
  • Outputs:
234 updated to: 230
146 updated to: 149

One simple way to do this only if necessary and only if both variable has same length:

Make a first comparison if the variables are the same, there was a change in the values:

echo/!_mPrevious!|find "!_mCurrents!" >nul && (
   endlocal & echo\Nothing changed^!! & goto :EOF )

And a second if they continue with the same length:

if !_i! neq !_j! endlocal & echo\Variables have different lengths^!! & goto :EOF

Obs.: 1. I prefer replace [ ] to one simple _

Obs.: 2. Also, change i+= to _i+=1+0, where no need predefined set command: set i=0

Io-oI
  • 2,514
  • 3
  • 22
  • 29
2

The FOR token delimiters are: <SPACE> <TAB> <NBSP> , ; =
Therefore, you can put it into a FOR loop, but it would fail if the content contained * or ?.

@echo off
====SETLOCAL EnableDelayedExpansion EnableExtensions
set/a"#=cnt=0"


::Define lists
set "mPrevious=229,234,235,127,58,0,131,133,146"
set  "mCurrent=229,230,235,127,58,0,131,133,149"


FOR %%P in (!mPrevious!) do (
    FOR %%C in (!mCurrent!) do (
        if !cnt! equ !#! echo(%%P %%C
        set/a"cnt+=1"
    )
    set/a"cnt=0,#+=1"
)
ScriptKidd
  • 803
  • 1
  • 5
  • 19
0

This is an approach using some self-expanding code:

@echo off
setlocal EnableDelayedExpansion

rem // Define constants here:
set "mPrevious=229,234,235,127,58,0,131,133,146"
set "mCurrents=229,230,235,127,58,0,131,133,149"

rem // Initialise auxiliary variables and indexes:
set "nPrevious=,%mPrevious%" & set /A "i=0"
set "nCurrents=,%mCurrents%" & set /A "j=0"

rem // Convert lists to arrays using self-expanding code:
set "_=%nPrevious:,=" & set /A "i+=1" & set "nPrevious[!i!]=%"
set "_=%nCurrents:,=" & set /A "j+=1" & set "nCurrents[!j!]=%"

rem // Verify availability of arrays:
> nul 2>&1 set nPrevious[ || set /A "i=0"
> nul 2>&1 set nCurrents[ || set /A "j=0"

rem // Determine minimal and maximal count:
if %j% gtr %i% (set /A "k=i, l=j" & set "_=#") else (set /A "k=j, l=i" & set "_=")

rem // Compare corresponding elements:
for /L %%K in (1,1,%k%) do if !nPrevious[%%K]! neq !nCurrents[%%K]! (
    echo [%%K]: !nPrevious[%%K]!    -^> !nCurrents[%%K]!
)

rem // Return removed or added elements:
set /A "k+=1" & for /L %%K in (!k!,1,%l%) do if defined _ (
    echo [%%K]: --- -^> !nCurrents[%%K]!
) else (
    echo [%%K]: !nPrevious[%%K]!    -^> ---
)

endlocal

Sample output, relying on the data of the question:

[2]:    234     ->      230
[9]:    146     ->      149
aschipfl
  • 33,626
  • 12
  • 54
  • 99