【问题标题】:PowerShell index[0] to the first instance of the string, index[1] to the second instance and so on till finishedPowerShell index[0] 到字符串的第一个实例, index[1] 到第二个实例,依此类推,直到完成
【发布时间】:2019-02-14 02:02:02
【问题描述】:

例如,将 LINE2 1243 替换为 LINE2 1,因为它位于 test.txt 的第 1 行。

# Find the line number: 
$lines = sls "LINE2" test.txt | Select-Object -ExpandProperty LineNumber

test.txt:

abc LINE2 1243
lmn LINE2 1250
xyz LINE2 1255

使用:

gc test.txt | % { $_ -replace "LINE2.*", "LINE2 $lines" }

我明白了:

abc LINE2 1 2 3
lmn LINE2 1 2 3
xyz LINE2 1 2 3

如何为字符串的第一个实例提供 index[0],并且仅提供 index[0],将 index[1] 提供给第二个实例,依此类推,直到完成。

换一种方式:

foreach ($line in $lines){
gc test.txt | % { $_ -replace "LINE2.*", "LINE2 $line" }
}

我明白了:

abc LINE2 1
lmn LINE2 1
xyz LINE2 1
abc LINE2 2
lmn LINE2 2
xyz LINE2 2
abc LINE2 3
lmn LINE2 3
xyz LINE2 3

如何将index[0] 仅用于字符串的第一个实例,依此类推。

【问题讨论】:

    标签: powershell windows-10-desktop


    【解决方案1】:

    您可以使用带有索引的 for 循环来实现这一点(如果我没听错的话);-)

    $lines = Select-String "LINE2" -Path C:\sample\test.txt | Select-Object -ExpandProperty LineNumber
    Get-Content -Path C:\sample\test.txt -OutVariable Content
    
    for ($index = 0; $index -lt $lines.count; $index++) {
        $Content[$index] -replace "LINE2.*", "LINE2 $($lines[$index])"
    }
    

    输出:

    abc LINE2 1
    lmn LINE2 2
    xyz LINE2 3
    

    【讨论】:

    • 我的原始帖子要求将输出发送到文本文件。所以我们保持在同一个页面上,你会怎么做?
    • 我没有看到这个请求。但无论如何 - 如果您喜欢将输出发送到文件,请使用 Out-File。
    • 写这个问题时,您的解决方案有效。它不适用于我的真实文件。请参阅stackoverflow.com/questions/54737787/… 处的解决方案
    【解决方案2】:

    这是一种有些不同的做事方式。 [咧嘴一笑]这是做什么的......

    • 读取文件
      我用 here-string 伪造了这个,但在真正这样做时使用 Get-Content。
    • 获取匹配行
      它使用-match 对集合起作用的方式来拉取与目标匹配的行。
    • 按空格分割
    • 从该数组中选择第一个两项
    • 向集合中添加一个 $Counter
    • 用空格分隔符连接三个项目
    • 将结果行发送到$Results 集合
    • 在屏幕上显示该集合
    • 将其保存到文本文件中

    这是代码...

    # fake reading in a text file
    #    in real life, use Get-Content
    $InStuff = @'
    cba line1 1234
    abc LINE2 1243
    mnl line4 1244
    lmn LINE2 1250
    zyx line9 1251
    xyz LINE2 1255
    qwe line9 1266
    '@ -split [environment]::NewLine
    
    $Target = 'Line2'
    
    $Counter = 1
    $Results = foreach ($IS_Item in ($InStuff -match $Target))
        {
        $IS_Item.Split(' ')[0..-1] + $Counter -join ' '
        $Counter ++
        }
    
    # on screen
    $Results
    
    # to a file
    $Results |
        Set-Content -LiteralPath "$env:TEMP\somebadhat.txt"
    

    在屏幕上...

    abc 1243 1
    lmn 1250 2
    xyz 1255 3
    

    在文本文件中...

    abc 1243 1
    lmn 1250 2
    xyz 1255 3
    

    【讨论】:

    • Windows-10 桌面。 PowerShell 5. 书面结果:cba 1266 1。预期结果:abc LINE2 2。 gc test.txt 在新的 PS 窗口中我得到:Method invocation failed because [System.Boolean] does not contain a method named 'Split'. 在新的 PS 窗口中按所写的方式运行,然后运行 ​​gc test.txt 没有“方法调用失败”
    • @somebadhat - 我发布的代码 - 与编写的完全一致 - 将在任何已升级到 ps5.1 的操作系统上的任何 ps5.1 会话中运行 - win10 应该始终 保持最新。当您运行 $PSVersionTable.PSVersion.ToString() 时,您的测试系统上的确切 PoSh 版本是什么?我在 win7ps5.1 设置中收到 5.1.14409.1018。
    • 5.1.17134.590。我已经解决了我的问题。你不需要再处理它了。
    • @somebadhat - 酷!很高兴知道你让它按需要工作了……[grin]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多