Home > PowerShell > Replacing file content

Replacing file content


One of my co-workers asked me if I knew an easy way to replace all the instances of a specific string inside a text file a little while ago. After 10 minutes of thinking about it I wrote him a very short PowerShell script which does the job nicely. At the time I didn’t think it worth writing about but I’ve decided to as it does highligh a few useful tips. So here’s the code of my Update-Content.ps1 script:
param
(
 $fileFilter,
 $find,
 $replace
)

Get-ChildItem * -filter $fileFilter -Recurse | ForEach-Object {
 (Get-Content $_.FullName) | ForEach-Object {$_ -replace $find, $replace} | Out-File $_.FullName -Force
}
It seems fairly self-explanatory but there are a few things that need to be born in mind here:
  • When using Get-Content in a pipeline, you need to remember that it will hold the file open for the duration of the pipeline process, as it is reading a line at a time. The fix is simple but not particularly obvious: put the Get-Content call in brackets. As this tells the parser to process the contents of the brackets prior to continuing, it will read the entire file contents in one go before passing the contents further down the pipeline.

 

  • Remember your context! I have two ForEach-Object loops inside each other in this example, so the $_ variable derives two local context settings with differing values. It is a common issue for subtle errors when people forget that the $_ variable from the outer loop is not accessible inside the inner loop. If you do need the value, place it in a new variable and use this in the inner loop.

 

  • The -replace operator uses global matching which means it replaces all matched entries from the input in a single call. Although this is probably what you wanted anyway, some language implementations of replace functionality default to replacing the first entry only. It is worth remembering if you use multiple languages on a regular basis.
Hopefully this is of use to you!
Chris.
About these ads
  1. October 14, 2010 at 7:23 am | #1

    Good tip. One of tips that can should how easy it is with PowerShell :)

    Personally, I would not use the inside foreach:
    gci c:\temp\webexpo2010\ *.txt | % {
    ($_|Get-Content) -replace $find,$replace | Out-File $_.fullname -force
    }

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: