【问题标题】:Using PowerShell to remove lines from a text file if it contains a string如果文本文件包含字符串,则使用 PowerShell 从文本文件中删除行
【发布时间】:2014-08-11 03:34:24
【问题描述】:

我正在尝试使用以下 PowerShell 代码从包含部分字符串的文本文件中删除所有行:

 Get-Content C:\new\temp_*.txt | Select-String -pattern "H|159" -notmatch | Out-File C:\new\newfile.txt

实际的字符串是H|159|28-05-2005|508|xxx,它在文件中重复多次,我试图只匹配上面指定的第一部分。那是对的吗?目前我的输出是空的。

我错过了什么吗?

【问题讨论】:

    标签: powershell powershell-2.0 powershell-3.0


    【解决方案1】:

    管道字符| 在正则表达式中具有特殊含义。 a|b 表示“匹配ab”。如果要匹配文字 | 字符,则需要对其进行转义:

    ... | Select-String -Pattern 'H\|159' -NotMatch | ...
    

    【讨论】:

    • 在 PowerShell 中,转义字符是反引号 (`)。见About Escape Characters
    • @orad 我知道这一点。然而,在正则表达式中,转义字符是反斜杠。在这种情况下两者都有效。
    【解决方案2】:

    逃离 |使用反引号的字符

    get-content c:\new\temp_*.txt | select-string -pattern 'H`|159' -notmatch | Out-File c:\new\newfile.txt
    

    【讨论】:

    • 警告 - 我用它来尝试就地更新文件,但文件已被删除。
    • 长线被Out-File分割,我用Set-Content解决了,语法相同
    【解决方案3】:

    假设你想把它写在同一个文件中,你可以这样做:

    Set-Content -Path "C:\temp\Newtext.txt" -Value (get-content -Path "c:\Temp\Newtext.txt" | Select-String -Pattern 'H\|159' -NotMatch)
    

    【讨论】:

    • 这正是我想要的。谢谢@Samselvaprabu!
    • 对于大型文本文件,这种方法速度很慢,您有什么想法可以提高性能吗?
    【解决方案4】:

    在现有答案的基础上写入同一文件的另一种选择。只需在内容发送到文件之前添加括号即可完成操作。

    (get-content c:\new\sameFile.txt | select-string -pattern 'H`|159' -notmatch) | Out-File c:\new\sameFile.txt
    

    【讨论】:

      【解决方案5】:

      在这种情况下您不需要Select-String,只需使用Where-Object 过滤掉这些行

      Get-Content C:\new\temp_*.txt |
          Where-Object { -not $_.Contains('H|159') } |
          Set-Content C:\new\newfile.txt
      

      String.Contains 进行字符串比较而不是正则表达式,因此您无需转义管道字符,而且速度也更快

      【讨论】:

      • 相比 Fourkeys,我更喜欢这个解决方案,因为(除非我是个白痴)Select-String 还会在输出中添加文件名和行号,这在我的用例中是不需要的。跨度>
      【解决方案6】:

      这可能是一个简单的问题,它确实允许我删除包含许多匹配项的行。我没有可以使用的部分匹配,并且需要在超过 1000 个文件上完成。 这篇文章确实帮助我到达了我需要的地方,谢谢。

      $ParentPath = "C:\temp\test"
      $Files = Get-ChildItem -Path $ParentPath -Recurse -Include *.txt
      $Match2 = "matchtext1"
      $Match2 = "matchtext2"
      $Match3 = "matchtext3"
      $Match4 = "matchtext4"
      $Match5 = "matchtext5"
      $Match6 = "matchtext6"
      $Match7 = "matchtext7"
      $Match8 = "matchtext8"
      $Match9 = "matchtext9"
      $Match10 = "matchtext10"
      
      foreach ($File in $Files) {
          $FullPath = $File | % { $_.FullName }
          $OldContent = Get-Content $FullPath
          $NewContent = $OldContent `
          | Where-Object {$_ -notmatch $Match1} `
          | Where-Object {$_ -notmatch $Match2} `
          | Where-Object {$_ -notmatch $Match3} `
          | Where-Object {$_ -notmatch $Match4} `
          | Where-Object {$_ -notmatch $Match5} `
          | Where-Object {$_ -notmatch $Match6} `
          | Where-Object {$_ -notmatch $Match7} `
          | Where-Object {$_ -notmatch $Match8} `
          | Where-Object {$_ -notmatch $Match9} `
          | Where-Object {$_ -notmatch $Match10}
          Set-Content -Path $FullPath -Value $NewContent
          Write-Output $File
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-19
        相关资源
        最近更新 更多