【问题标题】:Powershell - Read, Alter Line, Write new line over old in Text DocumentPowershell - 在文本文档中读取、更改行、在旧行上写入新行
【发布时间】:2020-09-29 00:53:02
【问题描述】:

我正在逐行阅读文本文件。如果我看到一个特定的字符串,我会找到一个特定字符的第一个和最后一个,使用两个子字符串创建一个较小的字符串,然后替换文本文件中的行。

困难的部分:我将文本行存储在一个变量中,但不知道如何在文本文档中的旧行上写下这个新行。

请原谅粗略的代码 - 我一直在测试东西,几个小时前才开始使用 PowerShell。

foreach($line in [System.IO.File]::ReadLines("C:\BatchPractice\test.txt"))
{
       Write-Output $line
       if ($line.Contains("dsa")) {
           Write-Output "TRUEEEEE"
           
       }
       $positionF = $line.IndexOf("\")+1
       $positionL = $line.LastIndexOf("\")+1
       $lengthT = $line.Length
       Write-Output ($positionF)
       Write-Output $positionL
       Write-Output $lengthT
       if($line.Contains("\")){
           Write-Output "Start"
            $combine = $line.Substring(0,$positionF-1) + $line.Substring($postionL,($lengthT-$positionL))
            Write-Output $combine
            $line1 = $line.Substring(0,$positionF-1)
            $line2 = $line.Substring($positionL,($lengthT-$positionL))
            $combined = $line1 + $line2
            Write-Output $combined
            Write-Output "Close"
       }
}```

【问题讨论】:

  • 可能更容易的方法。您应该举例说明文本文件的外观以及您尝试替换并最终得到的内容。了解在尝试写入同一个文件之前需要完成读取文件非常重要,因此最好将整个内容读入一个变量,然后在写出之前对其进行处理。

标签: powershell


【解决方案1】:

您可以将文件保存为Get-ContentSet-Content中的数组:

$file=(Get-Content "C:\BatchPractice\test.txt")

然后你可以像数组一样编辑它:

$file[LINE_NUMBER]="New line"

其中 LINE_NUMBER 是从 0 开始的行号。

然后覆盖到文件:

$file|Set-Content "C:\BatchPractice\test.txt"

您可以在代码中实现这一点。创建一个变量$i=0 并在循环结束时递增它。这里$i 将是每次迭代的行号。

HTH

【讨论】:

    【解决方案2】:

    根据您的代码,您似乎想要获取任何包含“dsa”的行并删除第一个反斜杠之后的内容,直到最后一个反斜杠。如果是这种情况,我建议使用正则表达式简化您的代码。首先我制作了一个示例文件,因为没有提供。

    $tempfile = New-TemporaryFile
    
    @'
    abc\def\ghi\jkl
    abc\dsa\ghi\jkl
    zyx\vut\dsa\srq
    zyx\vut\srq\pon
    '@ | Set-Content $tempfile -Encoding UTF8
    

    现在我们将读取所有行(除非这是一个大文件)

    $text = Get-Content $tempfile -Encoding UTF8
    

    接下来,我们将使用我们想要替换的模式创建一个正则表达式对象。双反斜杠是为了逃避反斜杠,因为它对正则表达式有意义。

    $regex = [regex]'(?<=.+\\).+\\'
    

    现在我们将遍历每一行,如果其中包含dsa,我们将对它运行替换,否则我们将输出该行。

    $text | ForEach-Object {
        if($_.contains('dsa'))
        {
            $regex.Replace($_,'')
        }
        else
        {
            $_
        }
    } -OutVariable newtext
    

    您会在屏幕上看到输出,但它也在$newtext 变量中捕获。我建议确保它是您在编写之前的输出。

    abc\def\ghi\jkl
    abc\jkl
    zyx\srq
    zyx\vut\srq\pon
    

    确认后,只需将其写回文件即可。

    $newtext | Set-Content $tempfile -Encoding UTF8
    

    显然你也可以组合这些步骤。

    $text | ForEach-Object {
        if($_.contains('dsa'))
        {
            $regex.Replace($_,'')
        }
        else
        {
            $_
        }
    } | Set-Content $tempfile -Encoding UTF8
    

    【讨论】:

      最近更新 更多