如何在 PowerShell 中分块管道中的项目?

How to chunk items from pipeline in PowerShell?

在我的 PowerShell cmdlet 中,我通过管道获取了任意数量的项目,并且想要 return 指定数量的项目块。

例如,当我的脚本作为输入时:

("A", "B", "C", "D", "E", "F", "G")

然后我定义,假设块大小为 4,我想 return 像这样:

(
    ("A", "B", "C", "D"),
    ("E", "F", "G")
)

如有任何帮助,我们将不胜感激。

您可以编写一个简单的函数,在生成新数组之前缓冲 N 个输入对象,然后在到达输入序列末尾时输出您可能遗留的任何缓冲值:

function chunk {
  param(
    [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
    [psobject]$InputObject,

    [ValidateRange(1, 100000)]
    [int]$ChunkSize = 4
  )

  begin {
    $counter = 0
    # Set up array that will act as buffer
    $chunk = [object[]]::new($ChunkSize)
  }

  process {
    # Add input object to next available slot in array
    $chunk[$counter++] = $InputObject

    if($counter -eq $ChunkSize){
        # If we've filled the buffer, output it as a new chunk
      Write-Output $chunk -NoEnumerate

      # Reset counter and buffer
      $counter = 0
      $chunk = [object[]]::new($ChunkSize)
    }
  }

  end {
    if($counter){
      # There's no more input but we have some data left over still, output it 
      Write-Output $chunk[0..($counter-1)] -NoEnumerate
    }
  }
}

现在您可以:

PS ~> $firstChunk,$nextChunk = "A", "B", "C", "D", "E", "F", "G" |chunk
PS ~> $firstChunk
A
B
C
D
PS ~> $nextChunk
E
F
G

如果我可以先将它保存到一个文件中,它可以使用 get-content 的 -readcount 参数。我无法将 2 个列表用常规数组和 += 包裹起来,所以我使用了一个数组列表,隐藏了 arraylist.add() 的输出。我希望你能像在 zsh 中那样动态地创建命名管道。

echo A B C D E F G | set-content file    # PS7:  'A'..'G'
get-content file -ReadCount 4 | 
  % { [collections.arraylist]$list = @() } { $list.add($_) > $null }


$list[0]

A
B
C
D


$list[1]

E
F
G