AJennings1
AJennings1

Reputation: 159

Write out string if it does not contain any array values in PowerShell

I have a simple program here that will write out a line within an array of lines if it does not contain any of the names within another array.

[array]$names = "Adam", "Bill", "Colin", "Dave"

[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

foreach ($line in $lines)
{
   if ($line -notmatch $names)
   {
       write $line
   }
}

When I run this, it just writes out every line from the array of lines, even though 'Adam' is included in the array of names. It should just write out 'My name is Jim' and 'My name is Sam'.

Sorry if this question is pretty basic but I couldn't find any answers for it.

Upvotes: 2

Views: 2994

Answers (3)

AJennings1
AJennings1

Reputation: 159

Thanks for the answers guys. I have reworked my code to make it a little simpler:

[array]$names = "Adam", "Bill", "Colin", "Dave"

[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

    foreach ($line in $lines)
    {
        $regex = $names -join '|'

        if ($line -notmatch $regex)
        {
            write $line
        }
    }

Upvotes: 0

Dave Sexton
Dave Sexton

Reputation: 11188

If you are using a regex comparison with -notmatch why not turn your list of names into a better regex? How about something like this:

$names = "Adam", "Bill", "Colin", "Dave"
$lines = "My name is Jim", "My name is Sam", "My name is Adam"

$regex = $names -join '|'

$lines | ? {$_ -notmatch $regex} | % {Write-Host $_}

Upvotes: 3

Mark Wragg
Mark Wragg

Reputation: 23355

There is probably a better solution than this, but one way to solve it is to have a second loop that iterates through each name and checks for them in the line:

[array]$names = "Adam", "Bill", "Colin", "Dave"
[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

foreach ($line in $lines)
{
    $names | ForEach-Object -Begin {$found = $false} {
        If ($line -match $_){ $found = $true; break } 
    } 

    if (-not $found)
    {
        write $line
    }
}

Explanation:

  • Sends $names via the pipeline in to ForEach-Object. This starts by initializing a $found variable within it's -Begin block.
  • ForEach-Object checks the line to match against each name (the name is now an item in the pipeline represented by $_). If it is found it sets $found to true and uses break to end the loop.
  • If $found is not true, it writes the line.

Upvotes: 1

Related Questions