35

I want to add content into the middle of a text file in Powershell. I'm searching for a specific pattern, then adding the content after it. Note this is in the middle of the file.

What I have currently is:

 (Get-Content ( $fileName )) | 
      Foreach-Object { 
           if($_ -match "pattern")
           {
                #Add Lines after the selected pattern
                $_ += "`nText To Add"
           }
      }
  } | Set-Content( $fileName )

However, this doesn't work. I'm assuming because $_ is immutable, or because the += operator doesn't modify it correctly?

What's the way to append text to $_ that will be reflected in the following Set-Content call?

Jeff
  • 5,746
  • 4
  • 33
  • 40
  • 1
    The only problem with your original is that you didn't output anything. Just append a $_ after the if(){} block ... – Jaykul Dec 09 '09 at 21:22

7 Answers7

55

Just output the extra text e.g.

(Get-Content $fileName) | 
    Foreach-Object {
        $_ # send the current line to output
        if ($_ -match "pattern") 
        {
            #Add Lines after the selected pattern 
            "Text To Add"
        }
    } | Set-Content $fileName

You may not need the extra ``n` since PowerShell will line terminate each string for you.

Michael Sorens
  • 35,361
  • 26
  • 116
  • 172
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
15

How about this:

(gc $fileName) -replace "pattern", "$&`nText To Add" | sc $fileName

I think that is fairly straight-forward. The only non-obvious thing is the "$&", which refers to what was matched by "pattern". More info: http://www.regular-expressions.info/powershell.html

dan-gph
  • 16,301
  • 12
  • 61
  • 79
3

This problem could be solved by using arrays. A text file is an array of strings. Every element is a line of text.

$FileName = "C:\temp\test.txt"
$Patern = "<patern>" # the 2 lines will be added just after this pattern 
$FileOriginal = Get-Content $FileName

<# create empty Array and use it as a modified file... #>

$FileModified = @() 

Foreach ($Line in $FileOriginal)
{    
    $FileModified += $Line

    if ($Line -match $patern) 
    {
        #Add Lines after the selected pattern 
        $FileModified += 'add text'
        $FileModified += 'add second line text'
    } 
}
Set-Content $fileName $FileModified
Community
  • 1
  • 1
0

I was attempting to do this, but with an XAML textbox. This thread gave me the starting point I needed to make it work.

For anyone else looking to do this:

#Find and replace matched line in textbox
$TextBox.Text = ($TextBox.Text) | 
Foreach-Object {
    if ($_ -match "pattern")
    {
        #Replace matched line 
        $_ -replace "pattern", "Text To Add"
    }
}
0
(Get-Content $fileName) | Foreach-Object {
        if ($_ -match "pattern") 
        {
            write-output $_" Text To Add"
        }
        else{
            write-output $_
            }
    } | Set-Content $fileName
D3l7a
  • 1
0

Below script works for inserting a text after a pattern for multiple files in the specified path

$fileNames = Get-ChildItem "C:\Example" -Recurse |
select -expand fullname

foreach ($FileName in $filenames) 
{
$pattern = "pattern"

[System.Collections.ArrayList]$file = Get-Content $FileName

$insertafter = @()

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

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


Set-Content $FileName $file
}
0

Solution for an exact match of text in a txt,properties,pf etc file.

$FileName = "C:\Progress\OpenEdge\properties\fathom.properties"
$Pattern = "[Fathom]"  
$FileOriginal = Get-Content $FileName

[String[]] $FileModified = @() 
Foreach ($Line in $FileOriginal)
{   
    $FileModified += $Line
    if ( $Line.Trim() -eq $Pattern ) 
    {
        #Add Lines after the selected pattern 
        $FileModified += "Autostart=true"
        
    } 
}
Set-Content $fileName $FileModified
Majedur
  • 3,074
  • 1
  • 30
  • 43