Comparing Arrays

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
ImAhNoBoDy
Posts: 11
Joined: 16 Nov 2016 12:03

Comparing Arrays

#1 Post by ImAhNoBoDy » 06 Dec 2016 04:54

I'm wondering how do you compare the results from one array to another? I'm trying not list users that are not logged in at the moment and then put the results in an array.

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "a=0"
SET "b=0"

FOR /F "SKIP=1 TOKENS=1 DELIMS=> " %%a IN ('QUERY USER') DO (ECHO %%a is logged on
FOR /F %%c IN ('DIR /B C:\Users') DO (IF %%c NEQ Public IF %%c NEQ NTUSER.DAT IF "%%~c" NEQ "%%~a" (SET PROFILE[!b!]=%%c& SET /A "b+=1") ELSE (ECHO %%c is not added)))
SET PROFILE[


I got the idea to put in %%~a from http://stackoverflow.com/questions/2295 … two-arrays, but it doesn't seem to be working. Anyone have any ideas?
Last edited by ImAhNoBoDy on 06 Dec 2016 07:24, edited 1 time in total.

Compo
Posts: 599
Joined: 21 Mar 2014 08:50

Re: Comparing Arrays

#2 Post by Compo » 06 Dec 2016 05:32

Firstly the code you have above has unbalanced parentheses and it also is performing case sensitive comparisons.

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "a=0"
SET "b=0"

FOR %%a IN ("%USERPROFILE%") DO (
   ECHO %%~nxa is logged on
   FOR /F %%c IN ('DIR/B/AD-S-H C:\Users') DO IF /I NOT "%%c"=="Public" (
      IF /I NOT "%%c"=="%%~nxa" (SET "PROFILE[!b!]=%%c"
         SET/A b+=1) ELSE (ECHO %%c is not added)))
SET PROFILE[
TIMEOUT -1

ImAhNoBoDy
Posts: 11
Joined: 16 Nov 2016 12:03

Re: Comparing Arrays

#3 Post by ImAhNoBoDy » 06 Dec 2016 06:44

Compo wrote:Firstly the code you have above has unbalanced parentheses and it also is performing case sensitive comparisons.

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "a=0"
SET "b=0"

FOR %%a IN ("%USERPROFILE%") DO (
   ECHO %%~nxa is logged on
   FOR /F %%c IN ('DIR/B/AD-S-H C:\Users') DO IF /I NOT "%%c"=="Public" (
      IF /I NOT "%%c"=="%%~nxa" (SET "PROFILE[!b!]=%%c"
         SET/A b+=1) ELSE (ECHO %%c is not added)))
SET PROFILE[
TIMEOUT -1


Thanks Campo. I edited the post to with the correct changes. Didn't know the script didn't run right as I had edited the script several times. haha.

Well the script above will only work on users with an active status. If another user was logged previously and another user just switched over, there will be one active user and one disconnected user. That's why I had to query the users logged on the computer. Any other suggestions?

Compo
Posts: 599
Joined: 21 Mar 2014 08:50

Re: Comparing Arrays

#4 Post by Compo » 06 Dec 2016 08:27

There's no reason why you cannot continue to 'query user' as before

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "b=0"

FOR /F "SKIP=1DELIMS=> " %%a IN ('QUERY USER') DO (ECHO %%a is logged on
   FOR /F %%c IN ('DIR/B/AD-S-H C:\Users') DO IF /I NOT "%%c"=="Public" (
      IF /I NOT "%%c"=="%%a" (SET "PROFILE[!b!]=%%c"
         SET/A b+=1) ELSE (ECHO %%c is not added)))
SET PROFILE[
TIMEOUT -1

ImAhNoBoDy
Posts: 11
Joined: 16 Nov 2016 12:03

Re: Comparing Arrays

#5 Post by ImAhNoBoDy » 06 Dec 2016 10:18

Hm....I just realized I didn't explain fully. The results of the array should not have any duplicate users. So I have a list with only 1 instance of the users logged on in the list and duplicates of users not logged in. So the list should be of only users not logged onto the computer. Is this possible? I'm still racking my brain trying to figure this out.

Compo
Posts: 599
Joined: 21 Mar 2014 08:50

Re: Comparing Arrays

#6 Post by Compo » 06 Dec 2016 10:45

I'm not sure what you're now suggesting.

The script I provided should set as variables with incrementing integers, (%PROFILE[i]%), 'all non hidden and non system users not called Public', (according to the second loop), 'who are not logged in', (according to the ouptut of the first for loop).

If that is not what you are getting or what you wanted then please explain.

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Comparing Arrays

#7 Post by Aacini » 06 Dec 2016 11:10

I am afraid I don't understand what exactly you are trying to do, but certainly is not "comparing arrays".

Perhaps you want to know "which elements appear in one array, but not in another". If so, then you may use this method:

Code: Select all

REM POPULATE THE ARRAY FROM 'QUERY USER'
FOR /F "SKIP=1 TOKENS=1 DELIMS=> " %%a IN ('QUERY USER') DO (
   ECHO %%a is logged on
   SET "PROFILE[%%a]=1"
)

REM REMOVE THE ELEMENTS FROM THE OTHER METHOD
FOR /F %%c IN ('DIR /B C:\Users') DO (
   SET "REMOVETHIS=YES"
   IF %%c NEQ Public IF %%c NEQ NTUSER.DAT IF "%%~c" NEQ "%%~a" SET "REMOVETHIS=NO"
   IF !REMOVETHIS! EQU YES (
      SET "PROFILE[%%~c]="
      ECHO %%c is not added
   )
)

SET PROFILE[

ImAhNoBoDy
Posts: 11
Joined: 16 Nov 2016 12:03

Re: Comparing Arrays

#8 Post by ImAhNoBoDy » 06 Dec 2016 11:41

Currently I'm logged in as User1 and User2 is disconnected.

When I run the script this is the results I'm getting:

Code: Select all

USER1 is logged on
USER1 is not added
USER2 is logged on
USER2 is not added
PROFILE[0]=USER2
PROFILE[10]=USER1
PROFILE[11]=USER3
PROFILE[1]=USER4
PROFILE[2]=USER5
PROFILE[3]=USER6
PROFILE[4]=USER7
PROFILE[5]=USER3
PROFILE[6]=USER4
PROFILE[7]=USER5
PROFILE[8]=USER6
PROFILE[9]=USER7


USER1 and USER2 gets added to the list, which is correct by the logic in the script, but not the desired result.

I want the results to be without duplicates of users not logged in like:

Code: Select all

PROFILE[0]=USER3
PROFILE[1]=USER4
PROFILE[2]=USER5
PROFILE[3]=USER6
PROFILE[4]=USER7


So in essence, whoever is logged in will not be on the final list of users currently not logged in the computer.



Aacini wrote:I am afraid I don't understand what exactly you are trying to do, but certainly is not "comparing arrays".

Perhaps you want to know "which elements appear in one array, but not in another". If so, then you may use this method:

Code: Select all

REM POPULATE THE ARRAY FROM 'QUERY USER'
FOR /F "SKIP=1 TOKENS=1 DELIMS=> " %%a IN ('QUERY USER') DO (
   ECHO %%a is logged on
   SET "PROFILE[%%a]=1"
)

REM REMOVE THE ELEMENTS FROM THE OTHER METHOD
FOR /F %%c IN ('DIR /B C:\Users') DO (
   SET "REMOVETHIS=YES"
   IF %%c NEQ Public IF %%c NEQ NTUSER.DAT IF "%%~c" NEQ "%%~a" SET "REMOVETHIS=NO"
   IF !REMOVETHIS! EQU YES (
      SET "PROFILE[%%~c]="
      ECHO %%c is not added
   )
)

SET PROFILE[


I actually wanted the reverse of that. Output of who is not logged in based on who is already logged in.

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Comparing Arrays

#9 Post by Aacini » 06 Dec 2016 11:54

ImAhNoBoDy wrote:I actually wanted the reverse of that. Output of who is not logged in based on who is already logged in.

In such a case, just swap the "Populate array" and "Remove elements" sections (with the appropriate data in each one, of course). You should get this result:

Code: Select all

PROFILE[USER3]=1
PROFILE[USER4]=1
PROFILE[USER5]=1
PROFILE[USER6]=1
PROFILE[USER7]=1

Antonio

Compo
Posts: 599
Joined: 21 Mar 2014 08:50

Re: Comparing Arrays

#10 Post by Compo » 06 Dec 2016 13:34

You could alternatively use this method:

Code: Select all

@Echo Off
SetLocal EnableDelayedExpansion
Set "i=0"
For /F "UseBackQSkip=1Delims=" %%A In (`WMIc /NameSpace:\\Root\CIMv2 Path^
 Win32_UserProfile Where "Special<>'True' And Loaded<>'True'" Get LocalPath`
) Do For /F "Delims=" %%B In ("%%A") Do Set "PROFILE[!i!]=%%~nxB%"&Set/A i+=1
Set PROFILE[
Timeout -1

Post Reply