I need to define an alias for this:
Select-String -NotMatch -Pattern "^[\t ]+\d"
so that I can use the alias instead of writing that long string each time.
After googling for 5 minutes and doing some experiments I came up with this:
filter foo {
$_ | Select-String -NotMatch -Pattern "^[\t ]+\d"
}
So now my script looks like this:
command1 | foo
command2 | foo
command3 | foo
command4 | foo
This is apparently working as expected, but I'm concerned about the efficiency implications of doing this.
Is the foo
filter acting as a transparent alias of the longer command line, or is it creating an entire new pipe or buffer or something?
Is the
foo
filter acting as a transparent alias of the longer command line, or is it creating an entire new pipe or buffer or something?
The latter, your current implementation is invoking Select-String
per pipeline input object instead of invoking it once and processing all input. If you care about performance you should change your implementation for a steppable pipeline:
function steppablefoo {
param([Parameter(ValueFromPipeline)] $InputObject)
begin {
$pipe = { Select-String -NotMatch -Pattern '^[\t ]+\d' }.GetSteppablePipeline()
$pipe.Begin($PSCmdlet)
}
process {
$pipe.Process($InputObject)
}
end {
$pipe.End()
}
}
You can test it for yourself with this performance comparison:
$tests = @{
Filter = {
0..300kb | foo
}
SteppablePipeline = {
0..300kb | steppablefoo
}
}
$tests.GetEnumerator() | ForEach-Object {
[pscustomobject]@{
Test = $_.Key
TotalMilliseconds = (Measure-Command { & $_.Value }).TotalMilliseconds
}
}