Powershell |特定模式后从.txt中删除行

问题描述

InputObject   : created_at : Tue Sep 24 02:31:26 +0000 2020
SideIndicator : =>

InputObject   : text       : CH#66551 by @Test: Testing this script to see if it works
SideIndicator : =>

InputObject   : created_at : Tue Sep 24 00:27:01 +0000 2020
SideIndicator : =>

InputObject   : text       : CH#34330 by Test: Fixed every thing that is able to breathe
SideIndicator : =>

InputObject   : created_at : Tue Sep 22 02:31:26 +0000 2020

InputObject   : text       : CH#66551 by @User2: Fixing stuff

InputObject   : created_at : Tue Sep 22 00:27:01 +0000 2020

InputObject   : text       : CH#34330 by User1: Seeing if it works

InputObject   : created_at : Mon Sep 21 15:54:20 +0000 2020

InputObject   : text       : CH#34294 by User1: Trying to find a workaround

InputObject   : created_at : Mon Sep 21 15:29:13 +0000 2020

InputObject   : text       : CH#34291 by User3: Doing something else

InputObject   : created_at : Mon Sep 21 15:03:15 +0000 2020

InputObject   : text       : CH#34286 by User3: Running around

InputObject   : 

InputObject   : 

我想删除此.txt文件中最后一个“ SideIndicator:=>”之后的所有内容 自从我是PowerShell新手以来,就非常感谢您的帮助。

解决方法

您可以简单地执行以下操作:

(Get-Content file.txt -Raw | Select-String -pattern '(?s).*SideIndicator : =>').Matches.Value |
    Set-Content newfile.txt

说明:

使用-Raw可以将文件作为单个字符串读取。这使单行模式(?s)可以有效地工作。单行模式允许.匹配换行符,从而可以轻松地跨多行匹配批量字符。

由于Select-String返回MatchInfo个对象,因此访问Value属性的Matches属性只会返回匹配的文本。

,

对不起,我错过了您的要求并重写了代码

也许不是最优雅的方式(我是新手...),但是我已经对其进行了测试,并且可以根据您的要求进行操作:

$path="C:\test\test.txt" #contains the data you ve shown in your question
$newPath="C:\test\test1.txt" #servs as a testfile to see if the data is correct

$end=(Get-Content -Path $path -Raw).LastIndexOf("SideIndicator : =>")
$length=("SideIndicator : =>").Length


(Get-Content -Path $path -Raw).Substring(0,$end+$length) | Add-Content -Path $newPath
,

这是一种获得我认为想要的方法。由于您未完全指定所需的内容,因此我抓取了与SideIndicator关联的两行,并从中建立了[PSCustomObject]。如果您需要较少的信息,请根据需要修改该部分。 [咧嘴]

它做什么...

  • 无法读取文本文件
    准备使用真实数据执行此操作时,请用对#region/#endregion的调用替换整个Get-Content块。
  • 设置目标以决定保留什么
  • 反复浏览
  • 测试目标
  • 如果找到,则会构建一个[PSCustomObject]来容纳所需的行
  • 如果未找到,则不执行任何操作
  • PSCO发送到$Result集合
  • 在屏幕上显示

代码...

#region >>> fake reading in a text file
#    in real life,use Get-Content
$InStuff = @'
InputObject   : created_at : Tue Sep 24 02:31:26 +0000 2020
SideIndicator : =>

InputObject   : text       : CH#66551 by @Test: Testing this script to see if it works
SideIndicator : =>

InputObject   : created_at : Tue Sep 24 00:27:01 +0000 2020
SideIndicator : =>

InputObject   : text       : CH#34330 by Test: Fixed every thing that is able to breathe
SideIndicator : =>

InputObject   : created_at : Tue Sep 22 02:31:26 +0000 2020

InputObject   : text       : CH#66551 by @User2: Fixing stuff

InputObject   : created_at : Tue Sep 22 00:27:01 +0000 2020

InputObject   : text       : CH#34330 by User1: Seeing if it works

InputObject   : created_at : Mon Sep 21 15:54:20 +0000 2020

InputObject   : text       : CH#34294 by User1: Trying to find a workaround

InputObject   : created_at : Mon Sep 21 15:29:13 +0000 2020

InputObject   : text       : CH#34291 by User3: Doing something else

InputObject   : created_at : Mon Sep 21 15:03:15 +0000 2020

InputObject   : text       : CH#34286 by User3: Running around

InputObject   : 

InputObject   : 
'@ -split [System.Environment]::NewLine
#endregion >>> fake reading in a text file

$Target = 'SideIndicator'

$Result = foreach ($Index in 0..$InStuff.GetUpperBound(0))
    {
    if ($InStuff[$Index] -match $Target)
        {
        [PSCustomObject]@{
            IO_Line = $InStuff[$Index -1]
            SI_Line = $InStuff[$Index]
            }
        }
    } # end >>> foreach ($Index in 0..$InStuff.GetUpperBound(0))

$Result

输出...

IO_Line                                                                                  SI_Line           
-------                                                                                  -------           
InputObject   : created_at : Tue Sep 24 02:31:26 +0000 2020                              SideIndicator : =>
InputObject   : text       : CH#66551 by @Test: Testing this script to see if it works   SideIndicator : =>
InputObject   : created_at : Tue Sep 24 00:27:01 +0000 2020                              SideIndicator : =>
InputObject   : text       : CH#34330 by Test: Fixed every thing that is able to breathe SideIndicator : =>
,

一种替代方法是使用LastIndexOf()

$txt = Get-Content -Path 'TheFullPathOfTheTxtFile' -Raw
$lastIndex = $txt.LastIndexOf("SideIndicator")
if ($lastIndex -ge 0) {
    # create a new text file here
    # $txt.Substring(0,($lastIndex + 18)) | Set-Content -Path 'TheFullPathOfThe_NEW_TxtFile'
    # for demo,just output on console screen
    $txt.Substring(0,($lastIndex + 18)) # 18 = length of "SideIndicator : =>"
}

或使用Select-String

$txt = Get-Content -Path 'TheFullPathOfTheTxtFile' -Raw
$txt.Substring(0,($txt | Select-String -Pattern '(?m)^SideIndicator' -AllMatches).Matches[-1].Index + 18)
,

我必须感谢你们所有人花时间帮助我。昨天我实际上找到了我测试过的(另一个)解决方案(compare-object left or right side only),效果很好。希望也能尝试您的建议;)