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!
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.
- This is is doable since
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.