Reputation: 59
I'm trying to remove items from an array that match special keywords. My array looks something like this:
$Printers =@('Printer Phone', 'Printer Building1', 'Printer XML', 'Printer Station', ...)
I want to remove all entries that match parts of certain strings, like filtering out every item that has "Phone" or "XML" in it's value. I thought of something like this but I'm not quiet sure if I'm on the right track:
$contains = @('Phone', 'XML')
$Printers -Filter * | Where-Object { $contains -contains $_.name }
Is there a simple way to achieve this?
Upvotes: 3
Views: 6524
Reputation: 27423
You can have an array of patterns with select-string. But select-string's output is a matchinfo object (unless it's converted to a string) and the line property has the original string examined.
$patterns = echo Phone XML
$printers = 'Printer Phone', 'Printer Building1', 'Printer XML',
'Printer Station'
$printers | select-string $patterns | % line
Printer Phone
Printer XML
Unfortunately, -contains is a frequent point of confusion.
'printer station' -contains 'station'
False
-split 'printer station' -contains 'station'
True
Upvotes: 2
Reputation: 338208
Three remarks
@()
to make arrays. The comma is what makes arrays, the @()
is redundant here.-contains
operator does not check whether a string contains a substring. It checks whether an array contains a value..Contains()
method works for substring checks, but be aware, it's case-sensitive. Lower-case your strings if you need case-insensitive comparisons (good enough and easier than doing it "by the book").{}
script block and don't assign to a variable, will become part of that script block's output. That's how the Where-Object
block below works.Code:
$Printers = 'Printer Phone','Printer Building1','Printer XML', 'Printer Station'
$contains = 'Phone','XML'
$Printers | Where-Object {
$printer = $_
$contains | Where-Object { $printer.Contains($_) }
}
Where-Object
considers non-empty output as $true
. So filtering $contains
down to something (or nothing) will decide whether the $Printers
value makes it. The above prints
Printer Phone
Printer XML
You could use -match
, but then you would have to start worrying about regex-escaping your $contains
values properly to avoid run-time errors.
Upvotes: 3
Reputation: 24592
Here is one way to do this.
> $contains = @('Phone', 'XML')
> $Printers = @('Printer Phone','Printer Building1','Printer XML', 'Printer Station')
> $Printers | Where-Object { $_ -Match ($contains -Join "|") }
Printer Phone
Printer XML
> $Printers | Where-Object { $_ -notMatch ($contains -Join "|") }
Printer Building1
Printer Station
Upvotes: 3