Niels Frederickx
Niels Frederickx

Reputation: 63

powershell: Append text before specific line instead of after

I'm looking for a way to add text before a line. To be more specific, Before a line and a blank space. Right now the scripts adds my text after the line [companyusers]. But I'd like to add the line before [CompanytoEXT] and before the blank space above [CompanytoEXT].

Does any body know how to do this?

Visual representation of what I'd want to do: https://i.sstatic.net/sEbK9.jpg

My current script:

$FileName = "C:\temptest\testimport - Copy.txt"
$Pattern = "[[\]]Companyusers"  
$FileOriginal = Get-Content $FileName

[String[]] $FileModified = @() 
Foreach ($Line in $FileOriginal)
{   
    $FileModified += $Line
    if ($Line -match $pattern) 
    {
        #Add Lines after the selected pattern 
        $FileModified += "NEWEMAILADDRESS"

    } 
    }

Set-Content $fileName $FileModified

Thanks for any advice!

Even if you're just pointing me where to look for answers it will be very much appreciated.

Upvotes: 3

Views: 6386

Answers (2)

arco444
arco444

Reputation: 22841

This might be easier using an ArrayList, that way you can insert new data easily at a specific point:

$FileName = "C:\temptest\testimport - Copy.txt"
$Pattern = "[[\]]Companyusers"
[System.Collections.ArrayList]$file = Get-Content $FileName
$insert = @()

for ($i=0; $i -lt $file.count; $i++) {
  if ($file[$i] -match $pattern) {
    $insert += $i-1 #Record the position of the line before this one
  }
}

#Now loop the recorded array positions and insert the new text
$insert | Sort-Object -Descending | ForEach-Object { $file.insert($_,"NEWEMAILADDRESS") }

Set-Content $FileName $file

First open the file into an ArrayList, then loop over it. Each time you encounter the pattern, you can add the previous position into a separate array, $insert. Once the loop is done, you can then loop the positions in the $insert array and use them to add the text into the ArrayList.

Upvotes: 3

TToni
TToni

Reputation: 9391

You need a little state machine here. Note when you have found the correct section, but do not insert the line yet. Insert only at the next empty line (or the end of the file, if the section is the last in the file).

Haven't tested, but should look like this:

$FileName = "C:\temptest\testimport - Copy.txt"
$Pattern = "[[\]]Companyusers"  
$FileOriginal = Get-Content $FileName

[String[]] $FileModified = @() 

$inCompanyUsersSection = $false

Foreach ($Line in $FileOriginal)
{   
    if ($Line -match $pattern) 
    {
        $inCompanyUsersSection = $true
    }

    if ($inCompanyUsersSection -and $line.Trim() -eq "")
    {
        $FileModified += "NEWEMAILADDRESS"
        $inCompanyUsersSection = $false
    } 

    $FileModified += $Line
}

# Border case: CompanyUsers might be the last sction in the file
if ($inCompanyUsersSection)
{
    $FileModified += "NEWEMAILADDRESS"
} 

Set-Content $fileName $FileModified

Edit: If you don't want to use the "insert at the next empty line" approach, because maybe your section may in clude empty lines, you can also trigger the insert at the beginning of the next section ($line.StartsWith("[")). However that would complicate things because now you have to look two lines ahead which means you have to buffer one line before writing it out. Doable but ugly.

Upvotes: 0

Related Questions