1

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?

1
  • 1
    First of all, you should use process block, because end (it is implicit end block as you do not use any) is executed after all previous commands already completed theirs execution. And for tips how to exit pipeline early you can use this answer. Commented Dec 16, 2016 at 21:30

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

3 Comments

Indeed, your command line works fast, but when I use 'head' instead of select-object directly, it hangs. This is even though it uses select-object. Hence my question about how to write it correctly
I don't understand the question, you don't need your function, you should jsut use select-object, it does stop the pipeline, so it won't read the whole file.
my function is shorter to type. and besides, the question is more general as I have more such functions.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.