IttayD
IttayD

Reputation: 29143

how to write streaming function in powershell

I tried to create a function that emulates Linux's head:

Function head( )
{
    [CmdletBinding()]
    param (
      [parameter(mandatory=$false, ValueFromPipeline=$true)] [Object[]] $inputs,
      [parameter(position=0, mandatory=$false)] [String] $liness = "10",
      [parameter(position=1, ValueFromRemainingArguments=$true)] [String[]] $filess
    )

    $lines = 0
    if (![int]::TryParse($liness, [ref]$lines)) {
      $lines = 10
      $filess = ,$liness + (@{$true=@();$false=$filess}[$null -eq $filess]) 
    }
    $read = 0

    $input | select-object -First $lines

    if ($filess) {
      get-content -TotalCount $lines $filess
    }
}

The problem is that this will actually read all the content (whether by reading $filess or from $input) and then print the first, where I'd want head to read the first lines and forget about the rest so it can work with large files.

How can this function be rewritten?

Upvotes: 1

Views: 331

Answers (1)

4c74356b41
4c74356b41

Reputation: 72181

Well, as far as I know, you are overdoing it slightly...
"Beginning in Windows PowerShell 3.0, Select-Object includes an optimization feature that prevents commands from creating and processing objects that are not used. When you include a Select-Object command with the First or Index parameter in a command pipeline, Windows PowerShell stops the command that generates the objects as soon as the selected number of objects is generated, even when the command that generates the objects appears before the Select-Object command in the pipeline. To turn off this optimizing behavior, use the Wait parameter."

So all you need to do is:

Get-Content -Path somefile | Select-Object -First 10 #or pass a variable

Upvotes: 1

Related Questions