简体   繁体   English

电源壳| 在特定模式后从 .txt 中删除行

[英]Powershell | Delete lines from .txt after specific pattern

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   : 

I want to remove everything in this .txt-file that comes after the last "SideIndicator : =>" Really appreciate the help since Im new to PowerShell.我想删除此 .txt 文件中最后一个“SideIndicator : =>”之后的所有内容,非常感谢我的帮助,因为我是 PowerShell 新手。

You can simply do the following:您可以简单地执行以下操作:

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

Explanation:解释:

Using -Raw allows the file to be read in as a single string.使用-Raw允许将文件作为单个字符串读入。 This enables single-line mode (?s) to work effectively.这使单行模式(?s)能够有效地工作。 Single-line mode allows .单行模式允许. to match newline characters, which makes it easy to match bulk characters across multiple lines.匹配换行符,这使得跨多行匹配批量字符变得容易。

Since Select-String returns MatchInfo objects, accessing the Value property of Matches property returns just the matched text.由于Select-String返回MatchInfo对象,因此访问Matches属性的Value属性仅返回匹配的文本。

Sorry I missread your requirement and rewrote the code抱歉,我看错了您的要求并重写了代码

Maybe not the most elegant way to do it (I am a newbie...) but I tested it and it works according to your requirement:也许不是最优雅的方法(我是新手......)但我测试了它并且它根据您的要求工作:

$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

here's one way to get what i think you want.这是获得我认为你想要的东西的一种方法。 since you did not specify exactly what you want, i grabbed both lines associated with the SideIndicator and built a [PSCustomObject] from them.由于您没有准确指定您想要什么,我抓住了与SideIndicator关联的两行并SideIndicator构建了一个[PSCustomObject] if you want less info, modify that section as desired.如果您想要更少的信息,请根据需要修改该部分。 [ grin ] [咧嘴笑]

what it does ...它能做什么 ...

  • fakes reading in a text file在文本文件中伪造阅读
    when ready to do this with real data, replace the entire #region/#endregion block with a call to Get-Content .当准备好使用真实数据执行此操作时,将整个#region/#endregion块替换为对Get-Content的调用。
  • sets the target to decide what to keep设定目标以决定保留什么
  • iterates thru the lines遍历行
  • tests for the target目标测试
  • if found, builds a [PSCustomObject] that holds the wanted lines如果找到,则构建一个包含所需行的[PSCustomObject]
  • if NOT found, does nothing如果未找到,则不执行任何操作
  • sends the PSCO out to the $Result collectionPSCO发送到$Result集合
  • displays that on screen在屏幕上显示

the code ...编码 ...

#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

output ...输出 ...

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 : =>

An alternative would be to use LastIndexOf() :另一种方法是使用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 : =>"
}

Or use Select-String :或使用Select-String

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

I have to thank all of you guys for taking time to help me out.我要感谢你们所有人抽出时间来帮助我。 Yesterday I actually found a(nother) solution ( compare-object left or right side only ) which I tested and works quite well.昨天我实际上找到了一个(另一个)解决方案(仅比较对象左侧或右侧),我测试了它并且效果很好。 Looking forward to try your suggestions too ;)也期待尝试您的建议;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM