在Foreach-Object循环中增加计数器

5
我想把文本文档中的每一行输出到一个单独的文档中,输出文档的名称为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++}

我在网上看到有人建议这样做,虽然这会增加计数器,但并没有达到我的要求(因为它仍然输出到同一个文件中)。

我不太确定在哪里插入counter ++,因为在Foreach-Object循环内部插入会导致错误(除非我插入的方式不正确)。

谢谢。

3个回答

4

对于您的情况,您可以使用Get-Content命令返回的ReadCount属性:

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

3

Martin Brandl的有用答案提供了一种有效的解决方案,基于 - 难以理解的 - ReadCount属性,该属性由Get-Content添加到每个输入行中,反映了从1开始的行号。

使用延迟绑定脚本块可以实现更短、更快的解决方案:

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

关于您尝试的内容:

ForEach-Object 命令的 -Process 块中必须递增变量 $counter,也就是执行每个输入对象的块(通常是唯一指定的块,以 位置 的方式)。

您传递的第二个脚本块 {$counter++} 绑定到 -End 参数,这意味着该块将在接收所有管道对象之后执行一次

因此,您可以使用以下代码:

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

增量操作嵌入在可扩展字符串中以简洁表述,但您也可以将其作为单独的语句。请注意,在表达式++ $ counter周围使用了额外的一对括号,以确保表达式的值也输出;默认情况下, ++ 只增加变量的值,但不产生输出。
外部的 $(...) - 子表达式运算符 - 必须嵌入可扩展字符串(“...”)中的表达式或命令。

2

在一行代码中,For-Each对象有三个位置块: begin, processend

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

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

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

因为如果您需要重复使用这个一行代码,$counter变量将不会被重置。您还可以在begin块中添加代码,以从其他值开始计数。
对于您的特定情况,我们只需在begin块中初始化$counter并使用mklement0的答案:
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"}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接