1

I have two txt files. Both contain a list of usernames:

List 1:

user1
user2
user3

List 2:

user1
user2
user7 

I want to compare these two lists. I want to know which users do not exist in both lists. So the output in this case should be a this list:

Endlist:

user3
user7

This is my code:

$list1 = get-content -Path "C:\list1.txt"
$list2 = get-content -Path "C:\list2.txt"

$endlist = foreach ($item in $list1) 
{
       if ($item -notmatch $list2)
       {
            [PSCustomObject]@{
            Name = $item 
       }

}
$endlist |Out-file "C:\endlist.txt"

What am I doing wrong?

user18209625
  • 139
  • 2
  • 15
  • 1
    see also: [Comparing two arrays & get the values which are not common](https://stackoverflow.com/q/6368386) – iRon Apr 26 '22 at 13:46
  • Please pick the answer that best solves your problem and click the big ✓ to the left of it to _accept_ it. This helps future visitors that have a similar problem to quickly find the "best" answer. – zett42 Apr 30 '22 at 16:25

3 Answers3

3

Normally you would use Compare-Object for this:

$list1 = 'user1', 'user2', 'user3'
$list2 = 'user1', 'user2', 'user7'

(Compare-Object $list1 $list2).InputObject # => user3, user7

If you want to do the comparison manually, and since you want to know the objects unique to either list, you would need two loops and the use of a containment operator (-notin or -notcontains in this case):

$list1 = (Get-Content list1.txt).Trim()
$list2 = (Get-Content list2.txt).Trim()

& {
    foreach($i in $list1) {
        if($i -notin $list2) { $i }
    }
    foreach($i in $list2) {
        if($i -notin $list1) { $i }
    }
} | Out-File "endlist.txt"
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
  • But if I just want to know which objects from list1 are not in list2, I tried this: $result = foreach ($item in $list1){ if($item -notin $list2){[PSCustomObject]@{Name=$item}}} ... the result file shows just all users from list1 but not the users who are in list1 but not in list2 ... Why? – user18209625 Apr 26 '22 at 13:56
  • 1
    @user18209625 my only guess is that `$list2` is not defined. Or you have not provided an actual representation of the contents of your files – Santiago Squarzon Apr 26 '22 at 14:02
  • $list 2 is defined. Could it be a problem that my objects are not quoted? My txt is like this: user1 user2 user3 (with a new line between every user) – user18209625 Apr 26 '22 at 14:11
  • 1
    @user18209625 see the update using `Trim()` on the lists, aside from that I have no idea what could be wrong – Santiago Squarzon Apr 26 '22 at 14:17
2

Complementing the existing working solutions, here is another one using a HashSet, which might be faster than Compare-Object:

[Collections.Generic.HashSet[string]] $list1 = Get-Content list1.txt
[Collections.Generic.HashSet[string]] $list2 = Get-Content list2.txt

$list1.SymmetricExceptWith($list2)
$list1

Output:

user7
user3

HashSet's strangely named1 SymmetricExceptWith method modifies the first set to contain only those elements that are unique to either set.

1) The mathematical term is symmetric difference.

zett42
  • 25,437
  • 3
  • 35
  • 72
1

Use compare-object

Compare-Object -ReferenceObject $list1 -DifferenceObject $list2 | Select-Object -ExpandProperty InputObject
guiwhatsthat
  • 2,349
  • 1
  • 12
  • 24