如何在 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
在我的 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