0

I'm trying to compare two arrays in batch script, but I'm afraid I'm doing it wrong. The code below retrieves the first 12 bytes from a file and tries to compare it with a given format.

Could you help help me with the TODO part?

PS: I'm not sure if I'm using the array variables correctly..

@echo off

SETlocal enabledelayedexpansion
SET read_byte_cmd=powershell -command Get-Content -encoding Byte -TotalCount 12 "'DB.accdb'" 

SET ACCESS_BYTES[0]=0
SET ACCESS_BYTES[1]=1
SET ACCESS_BYTES[2]=0
SET ACCESS_BYTES[3]=83
SET ACCESS_BYTES[4]=116
SET ACCESS_BYTES[5]=97
SET ACCESS_BYTES[6]=110 
SET ACCESS_BYTES[7]=100
SET ACCESS_BYTES[8]=97
SET ACCESS_BYTES[9]=114
SET ACCESS_BYTES[10]=100
SET ACCESS_BYTES[11]=32

echo list array --------------------
SET ACCESS_BYTES[
echo\

echo list file bytes --------------
set i=0
for /f "tokens=1 delims==" %%i in ('%read_byte_cmd%') do (
    set /A i+=1
    echo %read_byte_array[!i!]%=%%i
    )
echo\

echo list values only --------------
for /f "tokens=2 delims==" %%i in ('SET ACCESS_BYTES[') do echo %%i
echo\

echo comparison --------------------
:: TODO compare ACCESS_BYTES[i] with read_byte_array[i], if equal success..
4
  • 1
    You define your array starting with 0, but in your for loop you start to index with 1 (enter the for with i=0, adding one, then echo...[!i!]. Intention or logical quirk? Commented May 30, 2016 at 10:26
  • Do all bytes need to be the same? If so, couldn't you just compare a single variable with all bytes (using ; as delimiter if needed) to see if they are equal. Commented May 30, 2016 at 12:13
  • @Stephan No quirk, only the result of multiple tries to fix the code... Commented May 30, 2016 at 15:23
  • @Dennis All bytes have to be the same, but besides that, there is no limitation regarding how it should be done. Array vs array was just my 1st approach.. Commented May 30, 2016 at 15:23

2 Answers 2

1

I think you're looking for something like this:

@echo off

SETlocal enabledelayedexpansion
SET read_byte_cmd=powershell -command Get-Content -encoding Byte -TotalCount 12 "'DB.accdb'" 

SET "ACCESS_BYTES=[0,1,0,83,116,97,110,100,97,114,100,32]"
set "READ_BYTES=["
for /f "tokens=1 delims==" %%i in ('%read_byte_cmd%') do (
    set "READ_BYTES=!READ_BYTES!%%i,"
)
set "READ_BYTES=%READ_BYTES:~0,-1%]"
echo %ACCESS_BYTES%
echo %READ_BYTES%
echo.
if "%READ_BYTES%"=="%ACCESS_BYTES%" echo same
if not "%READ_BYTES%"=="%ACCESS_BYTES%" echo not the same
pause

This doesn't use the arrays, but just compares two variables.

Sign up to request clarification or add additional context in comments.

6 Comments

Dennis, thanks a bunch. But I'm still dwelling with it. Your code stops at element [1], printing the message "byte 1, value 1 is not equal to", when it should cycle through all elements (because they are equal). It seems like the code is not iterating through the array ACCESS_BYTES (always stays at 0)...
@lbrunolx error on my part, could you tell me if it gives a better message now? I also made the loop start at 0, not at 1. Did it print succes before the error message?
Dennis, I'm afraid it is still stopping at [1]. I get: read_byte_array[0]=0 correct read_byte_array[1]=1 byte 1, value 1 is not equal to 0 not all bytes were the same
@lbrunolx seems like I messed up my delayed expansion, will fix that in a minute
@lbrunolx yeah, the final problem was that the variable i contained a number, which caused it to sometimes be interpreted (when using an escaped %% aproach) as %1, which starts looking at parameters of the batch file. However, this approach doesn't have that problem
|
1

Your batch script is invoking PowerShell, which is a much more powerful language for data processing. Why not also do the comparison in PowerShell? The Compare-Object cmdlet (alias diff) can quickly compare two arrays, and the array syntax is PowerShell is much simpler than CMD.

Compare-AccessBytes.ps1

$bytes = Get-Content -Encoding Byte -TotalCount 12 'DB.accdb'
$target = @(0,1,0,83,116,97,110,100,97,114,100,32)

if ((diff $bytes $target).length -eq 0) {
  "Matching"
} else {
  "Different"
}

To invoke from batch

PowerShell.exe -ex bypass -f Compare-AccessBytes.ps1

If you need to capture this into a batch variable, use for /F syntax to capture the output of the script.

for /f %%a in ('PowerShell.exe -ex bypass -f Compare-AccessBytes.ps1') do if "%%a"=="Matching" (echo Yep, it matches.) else (echo Sorry, nope)

Finally, if a batch file is the only audience for your .ps1, it is even easier to have PowerShell communicate directly with CMD in its native dialect: Exit codes.

Compare-AccessBytes2.ps1

$bytes = Get-Content -Encoding Byte -TotalCount 12 'DB.accdb'
$target = @(0,1,0,83,116,97,110,100,97,114,100,32)
if ((diff $bytes $target).length -eq 0) { exit 12345 }

In your batch, run the command and check ERRORLEVEL.

PowerShell.exe -ex bypass -f Compare-AccessBytes.ps1
if %ERRORLEVEL% EQU 12345 (
   echo "Declare a holiday, the bytes match!"
) else (
   echo "So sad, no match today."
)

1 Comment

Thank you, Ryan. Much appreciated :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.