Foreach-Object循环内的增量计数器

时间:2018-11-26 18:46:00

标签: powershell loops foreach

我想将文本文档中的每一行输出到其自己的文档中,其中输出文档名为1.txt,2.txt等。 这是我的初始代码,它读取文本文档并逐行输出行。

get-content "artists.txt" | Foreach-Object {$_ | set-content "artists\$counter.txt"}

但是您可以想象,它总是输出到同一文档。

我尝试过

get-content "artists.txt" | 
  Foreach-Object {$_ | set-content "artists\$counter.txt" } {$counter++}
正如我在网上看到的建议

,虽然这会增加计数器的数量,但它并没有执行我想要的操作(因为它仍然输出到同一文件)。

不确定在Foreach-Object循环内部将计数器++插入到哪里,这本身会给我一个错误(除非我将其插入错误)。

谢谢。

3 个答案:

答案 0 :(得分:4)

对于您而言,可以使用ReadCount cmdlet返回的Get-Content属性:

get-content "artists.txt" | Foreach-Object {$_ | set-content "artists\$($_.ReadCount).txt" }

答案 1 :(得分:3)

Martin Brandl's helpful answer提供了一个有效的解决方案,基于ReadCount添加到每条输入行的-名字模糊不清-Get-Content,它反映了基于1行号

使用delay-bind script block可以使解决方案更短且明显更快:

Get-Content artists.txt | Set-Content -LiteralPath { "artists\$($_.ReadCount).txt" }

关于您尝试过的事情

变量$counter必须在ForEach-Object命令的-Process块(即,为每个输入对象执行的块(通常是仅 >指定的块,按位置)。

您传递的第二个脚本块{$counter++}绑定到-End参数,这意味着要在一次之后全部执行管道对象已收到。

因此,您可以使用以下内容:

$counter = 0
Get-Content artists.txt | Foreach-Object { 
  $_ | Set-Content "artists\$((++$counter)).txt"
}

为简便起见,递增操作嵌入在可扩展字符串中,但您可以将其单独声明。

请注意在表达式(...)周围使用一对额外的++$counter,以确保表达式的值也是 output ;默认情况下,++只会增加变量的值,但不会产生输出。
为了将表达式或命令嵌入可扩展字符串($(...))中,需要外部"..."-子表达式运算符。

答案 2 :(得分:1)

在一种情况下,每个对象都有三个位置块:beginprocessend

...<piped objects>... | For-Each {...begin...} {...process...} {...end...}

设置计数器的一种简单而通用的方法是:

...<piped objects>... | For-Each {$counter = 0} {...process...} {...end...}

因为如果您需要重用单线纸,$counter变量将不会被重置。您还可以将代码添加到begin块中,以从其他位置开始计数器。

对于您的特定情况,我们只需要在$counter块中初始化begin并使用mklement0's答案:

get-content "artists.txt" | Foreach-Object {$counter = 0} {$_ | set-content "artists\$((++$counter.txt))"}

您甚至可以使用end块来输出摘要:

For-Each {...} {...} {Write-Host "There were $counter lines read and $counter files created"}