【问题标题】:Increment counter inside Foreach-Object loopForeach-Object 循环内的增量计数器
【发布时间】:2019-04-28 11:02:27
【问题描述】:

我想将文本文档中的每一行输出到其自己的文档中,其中输出文档名为 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 循环内部本身会给我一个错误(除非我插入错误)。

谢谢。

【问题讨论】:

    标签: powershell loops foreach


    【解决方案1】:

    在您的情况下,您可以使用 Get-Content cmdlet 返回的 ReadCount 属性:

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

    【讨论】:

      【解决方案2】:

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

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

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

      至于你尝试了什么

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

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

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

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

      为简洁起见,增量操作嵌入在可扩展字符串中,但您可以将其设为单独的语句。

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

      【讨论】:

        【解决方案3】:

        在单行中,For-Each 对象具有三个位置块:beginprocessend

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

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

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

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

        对于您的特定情况,我们只需在 begin 块中初始化 $counter 并使用 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"}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-12-14
          • 2017-06-27
          • 2011-06-19
          • 1970-01-01
          • 1970-01-01
          • 2021-12-30
          • 2021-01-13
          • 2020-05-11
          相关资源
          最近更新 更多