'How to compare dotnet packages and txt
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:
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!
Solution 1:[1]
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
$matchesto$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
$matcheswas populated and if it wasn't, output that nothing was found.- This is is doable since
-matchwill populate the$matchesvariable when something is found. - If nothing is found, the variable won't be populated.
- This is is doable since
Solution 2:[2]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |

