Home > other >  How to compare dotnet packages and txt
How to compare dotnet packages and txt

Time:04-15

I have the script:

$Test = (dotnet list C:\Tasks.Api.csproj package) and it provides some packages (WITH 2 SPACES ON THE END!):

Project 'Tasks.Api' has the following package references 
   [net5.0]:  
   Top-level Package                               Requested   Resolved 
   > AspNetCore.HealthChecks.SqlServer             6.0.0       6.0.0    
   > Microsoft.ApplicationInsights.AspNetCore      2.18.0      2.18.0   
   > Microsoft.EntityFrameworkCore.Tools           5.0.11      5.0.11   
   > Swashbuckle.AspNetCore                        6.2.3       6.2.3
 (SPACE)
 (SPACE)

gettype provide next:

enter image description here

Then I have a "good" file (txt):

AspNetCore.HealthChecks.SqlServer
Microsoft.ApplicationInsights.AspNetCore

Now I want to know, does my "good" file contains lines from $Test or not?

I think I tried millions of other options, but now I'm stuck on it:

$whiteliste = Get-Content C:\whitelist.txt 
$test = (dotnet list C:\Tasks.Api.csproj package) 
$array = @() 
$test[3..($test.Length-2)] | foreach { 
$array =$_ 
} 
Foreach ($item in $array) { 
Write-host "!!!" $item 
$containsWord = $whiteliste | %{$_ -contains $item.Remove(" ")} 
if ($containsWord -contains $true) { 
    Write-Host "There is!" 
} else { 
    Write-Host "There ins't!" 
} 
} 

Thanks!

CodePudding user response:

Without getting fancy, a simple solution would be to use the -Match operator to find those package references seeing as they're unique names, and we can make use of some user friendly RegEx:

$whiteliste = (Get-Content -Path "C:\whitelist.txt").Foreach{[regex]::Escape($_.Trim())} -join "|"
$test.Foreach{
    if ($_ -match $whiteliste) {
        Write-Host -Object "Found: [$($Matches[0])]"
    }
}

Edit: Based on your comment on Santi's post, if you would like it to tell you if there is no matches found, you can add a Begin, Process, and End clause:

$test.ForEach{
    Begin { $Matches = $null }
    Process { 
        if ($_ -match $tomatch) { 
            Write-Host -Object "Found: $($Matches[0])" 
        } 
    }
    End { 
        if ($null -eq $Matches) { 
            "No Match Found:(" 
        } 
    }
}
  • First, the Begin clause will set the automatic variable of $matches to $null; this way it doesn't interfere with past matches.
  • Then, the Process clause will run your code to add to $matches.
  • Finally, the End clause will check to see if $matches was populated and if it wasn't, output that nothing was found.
    • This is is doable since -match will populate the $matches variable when something is found.
    • If nothing is found, the variable won't be populated.

CodePudding user response:

I believe you can use -match for checking this, -contains will only work with exact matches of an array.

Here is a minimal example:

$test = dotnet list C:\Tasks.Api.csproj package
$good = Get-Content goodfile.txt

foreach($i in $test) {
    foreach($z in $good) {
        if($i -match $z) {
            "I've got a match!!! [ $i ]"
            # no need to keep comparing, `break` the inner loop
            break 
        }
    }
}

Which would result in:

I've got a match!!! [ > AspNetCore.HealthChecks.SqlServer             6.0.0       6.0.0 ]
I've got a match!!! [ > Microsoft.ApplicationInsights.AspNetCore      2.18.0      2.18.0 ]

Another great alternative would be using -like and adding wildcards to the RHS of the comparison, as pointed out by shadow2020 in his helpful comment:

if($i -like "*$z*") {
    "I've got a match!!! [ $i ]"
    break
}

Following your last comment, how can we add a comment if there was no match:

:outer foreach($i in $test) {
    # if this line is only white space, skip it
    if([string]::IsNullOrWhiteSpace($i)) {
        continue
    }
    
    foreach($z in $good) {
        if($i -match $z) {
            "I've got a match!!! [ $i ]"
            # no need to keep comparing,
            # `continue` with the next element of the outer loop
            continue outer
        }
    }

    # if we're here, no element of `$good`
    # was matched with all elements of `$test`
    "Couldn't find a match for [ $i ]"
}

The result of this would be:

Couldn't find a match for [ [net5.0]: ]
Couldn't find a match for [ Top-level Package                               Requested   Resolved ]
I've got a match!!! [ > AspNetCore.HealthChecks.SqlServer             6.0.0       6.0.0 ]
I've got a match!!! [ > Microsoft.ApplicationInsights.AspNetCore      2.18.0      2.18.0 ]
Couldn't find a match for [ > Microsoft.EntityFrameworkCore.Tools           5.0.11      5.0.11 ]
Couldn't find a match for [ > Swashbuckle.AspNetCore                        6.2.3       6.2.3 ]

See Using a labeled continue in a loop which describes and explains the use of continue outer in this example.

  • Related