Powershell Replace-String Function

PowerShell doesn’t include the ability to do a mass search-and-replace. As I was just looking for a good way to do this, it so happened that at around the same time someone asked the question in the newsgroups, and got a good answer from Keith Hill.

I took what Keith wrote, and sort of consolidated it into a one line function:

function Replace-String($find, $replace, $includes)
{
    get-childitem $includes | select-string $find -list |% { (get-content $_.Path)
         |% { $_ -replace $find, $replace } | set-content $_.Path }
}

(Note: The function contents should all be on one line, I just wrapped it for formatting on the website.)

One point to note that I have a question on: I chose to “filter” (bad choice of word, I realize) the replacement using the “select-string” cmdlet. In his book, Windows PowerShell in Action, Bruce Payette mentions that select-string has been optimized for searching for strings in files, so I figured that even though it meant searching through files twice for a pattern, it might speed up the function if I used select-string to prevent me from iterating over the contents of each and every file, even if they did not contain a match for the search. On another up-side, I suppose it also helps prevent me from indirectly “touching” each file (and thus inadvertantly modifying the timestamp on every searched file).

Was that the right decision to make? Thoughts?

This entry was posted on Wednesday, March 28th, 2007 at 7:48 am and is filed under powershell. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

10 Responses to “Powershell Replace-String Function”

  1. aaron Says:

    Good point, it’s a messy solution, but sometimes it’s what we have to do. :)

  2. schallm Says:

    This code/function works for simple regular expressions, but if you need to replace across lines it will not work. Unfortunately I can’t seem to get Select-String to work across lines, so you would need to have a $narrow as well as a $find. The @narrow would be a single line regex that would narrow the number of files you would perform the full $find regex on. Here is updated code. This will read the whole file into a string, so it may use a chunk of memory for large files…

    Get-ChildItem $includes | Select-String $narrow -list | % { [string]::join(“`n”, (Get-Content $_.Path)) -replace $find, $replace | set-content $_.Path }

  3. Refactoring C# with PowerShell - Aaron Lerch Says:

    [...] Note that this function relies on my "Replace-String" function, found here. [...]

  4. Refactoring C# with PowerShell | Aaron Lerch Says:

    [...] Note that this function relies on my “Replace-String” function, found here. [...]

  5. Anonymous Says:

    Hi there ;)

    Just what I needed. I think that you may also ommit the first cmdlet (get-childitem) and incorporate it into select-string using the the -path option. Just my two cents ;)

  6. moshe ro Says:

    Hi,
    Exactly what I need :
    I wrote a PS script that contain a lot of string replacements in files ,and your function Replace-String made it simple and readable.

  7. Byteway Says:

    How can I replace (special characters) within a servicename the “$” sign for a “?”. When I escape the $ character within the service name, it is not accepted:
    $servicename = AOS$01
    stop-Service $servicename (this returns errors: service name can not be found)

    Changing the servicename to:
    $servicename = AOS\$01
    $servicename = AOS’$01
    does not work ???

    Please can you give a tip on how to solve this?

    Regards,
    Byteway

  8. search Says:

    Search and replace should be a basic feature for a lot of things. I see lots of applications not even providing this feature, which is pull your hair out frustrating.

  9. CodeRover Says:

    How can one use PowerShell to replace Carriage Return character in a MS Excel spreadsheet with an empty space?

  10. aaron Says:

    I think you could use the Excel COM API from within powershell (though I haven’t tried it so I don’t have much specific advice). Maybe this link will be helpful…
    http://blogs.technet.com/heyscriptingguy/archive/2006/09/08/how-can-i-use-windows-powershell-to-automate-microsoft-excel.aspx