0
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.

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
Freak6on
  • 1
  • 2
  • wouldn't it make more sense to filter this when you still have things as _objects_ instead of after you convert them to mere strings? – Lee_Dailey Sep 22 '20 at 05:54
  • Probably. As you can see on the output here, I only want the InputObject(s) with "SideIndicator : =>". The other Input objects you can see are from the "SideIndicator : <=" which I want to get removed from the final output. – Freak6on Sep 22 '20 at 06:10
  • if you must do it the backwards way [*grin*], then try matching for `SideIndicator ` and taking the line above it. if you iterate thru the collection by line you can grab the previous line just by using `$Index - 1`. – Lee_Dailey Sep 22 '20 at 06:13
  • Could you please translate that into code or give me an example that I can use for that? – Freak6on Sep 22 '20 at 06:20
  • To Lee's point, `Compare-Object` does not include matches by default. You can exclude `-IncludeEqual` from the command that exported this, and your final output will include what you are looking for. – Andrew Ryan Davis Sep 22 '20 at 06:32
  • @Freak6on - please take a look at my Answer. i think it demos the idea fairly well. [*grin*] – Lee_Dailey Sep 22 '20 at 08:15

5 Answers5

2

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. This enables single-line mode (?s) to work effectively. 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.

AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
0

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
Adis1102
  • 192
  • 1
  • 11
0

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. 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.
  • 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
  • if NOT found, does nothing
  • sends the PSCO out to the $Result collection
  • 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 : =>
Lee_Dailey
  • 7,292
  • 2
  • 22
  • 26
0

An alternative would be to use 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:

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

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 ;)

Freak6on
  • 1
  • 2