Hey, Scripting Guy! How Can I Use Windows PowerShell to Replace Characters in a Text File?

Hey, Scripting Guy! Question

Hey, Scripting Guy! Using Windows PowerShell, how can I replace all the asterisks in a text file with some other character?

-- RC

SpacerHey, Scripting Guy! AnswerScript Center

Hey, RC. You know, a lot of people ask the Scripting Guy who writes this column, “How do you do it? How do you manage to write a new column each and every day?” (Of course, lots of other people ask him why he writes a new column each day. But that’s another story.) “Every single day,” they’ll marvel. “Don’t you ever get too sick or too tired to write Hey, Scripting Guy!?”

Believe it or not, the answer to that is no, the Scripting Guy who writes this column never gets too sick or too tired to write Hey, Scripting Guy!; in fact, the Scripting Guy who writes this column is probably the healthiest person in the entire world. Is that due to a rigorous program of diet and exercise? Well, no, not really, not unless you count watching TV as exercise, and not unless doughnuts are now considered part of a healthy diet. Instead, the Scripting Guy who writes this column is healthy for one reason and one reason only: he’s overworked and overstressed.

It’s true: work-related stress is supposedly good for you. Researchers in Europe recently discovered that people are more likely to get sick when they are on vacation than when they go to work every day. The researchers theorized that this is because the stressors in the workplace trigger the body’s defense mechanisms, making it easier for you to ward off sickness and infections. When you’re at home you relax; in turn, your body lets down its guard, and – wham! – before you know it you’ve caught a cold or the flu. To be truly healthy, you need those workplace stressors.

And that’s good news for the Scripting Guy who writes this column. After all, if workplace stressors make you healthy, well, he’ll probably live to be 190 years old. At the very least, he’ll be around – and working – for a long time to come.

Which probably comes as a huge thrill to his old friend the Scripting Editor.

Note. Just think, Scripting Editor: we’ll be a team for many more decades to come! That might not sound like much fun, but just imagine how healthy that should make you.

Considering the fact that we’ve spent the morning trying to figure out how to write Perl scripts (in preparation for the upcoming 2008 Winter Scripting Games), we’re feeling especially … healthy … today. With that in mind, let’s see if we can figure out how to use Windows PowerShell to replace characters in a text file. For example, suppose we have the following text file (C:\Scripts\Test.txt):

This is line 1.*
This is line 2*.
*This is line 3.
This is * line 4.

Let’s further suppose that (for some reason) we want to replace those pesky asterisks (*) with at signs (@). How can we do that? Well, this script should do the trick:

(Get-Content C:\Scripts\Test.txt) | 
Foreach-Object {$_ -replace "\*", "@"} | 
Set-Content C:\Scripts\Test.txt

As you can see, there really isn’t much to this script; in fact, if we had slightly-wider Web pages we would have put the whole thing on a single line. We start out by using the Get-Content cmdlet to read in the text from the file C:\Scripts\Test.txt; by default, the text gets read in as an array, with each item in the array representing a single line in the text file. Oh, and notice that we enclosed the Get-Content command in parentheses. Why did we do that? Because that way we can be sure that PowerShell will read in the entire contents of the file before it does anything else.

So what happens after PowerShell has read in the entire contents of the text file? Well, our next step is to pipe those contents to the Foreach-Object cmdlet. As we pointed out a moment ago, when PowerShell reads in the contents of a text file it automatically turns that information into an array. What the Foreach-Object cmdlet will do now is loop through each and every item in that array; in other words, it will loop through each and every line in the text file. And for each of those lines Foreach-Object will execute the following scriptblock:

{$_ -replace "\*", "@"}

As you probably know, in a Windows PowerShell pipeline the $_ represents the current object. In this case, the first time we go through the loop $_ will represent the first line in the text file; the second time we go through the loop $_ will represent the second line in the text file; and so on. For each of these lines (that is, for each of these string values) we’re going to use the Replace method to replace all the asterisks in the line with an @ sign. To do that we simply specify the target character (an asterisk), followed by the replacement text (the @ sign).

The only tricky part here is that the asterisk is a reserved character in Windows PowerShell; because of that we need to “escape” the character before we can perform a search-and-replace operation using that character. How hard is that? Not hard at all; we just need to preface the asterisk (or any other reserved character) with a \:


And yes, that is important. If you leave out the slash mark you’ll get an error message like this each time you run through the loop:

Invalid regular expression pattern: *.
At C:\scripts\test.ps1:2 char:33
+ Foreach-Object {$_ -replace "*",  <<<< "@"} |

Of course, you must also keep in mind that the only reason we need to escape the asterisk is because the asterisk is a reserved character in regular expressions. If you want to search for something that isn’t a reserved character then make sure you leave the \ off:

{$_ -replace "a", "@"}

So, in other words, sometimes we need a \ and sometimes we don’t? How are we supposed to know when we need to escape a character and when we don’t? You guys are making my head hurt.

Listen, don’t worry about it; remember, stress is good for you. (Which means that we probably should have said, “Go ahead and worry.” After all worrying is pretty stressful.) You don’t have to remember which characters are reserved characters; we’ll tell you which characters are reserved characters. We can’t say for sure that the following list (taken from MSDN) represents a complete list of reserved characters, but it’s a good place to start:

  • $
  • ()
  • *
  • +
  • .
  • []
  • ?
  • \
  • /
  • ^
  • {}
  • |

OK, back to the script. After Foreach-Object finishes off its search-and-replace operation, our virtual text file is then handed off to the Set-Content cmdlet; in turn, Set-Content writes the modified data back to the file C:\scripts\Test.txt:

Set-Content C:\Scripts\Test.txt

And that’s it; at that point we’re done.

You know, you’re right: that did seem a little too easy, didn’t it? Well, let’s take a peek at Test.txt and see what happened, if anything:

This is line 1.@
This is line 2@.
@This is line 3.
This is @ line 4.

Well, what do you know: it really was that easy, wasn’t it?

We hope that answers your question, RC; if it doesn’t, please let us know. In the meantime, the Scripting Guy who writes this column is in a bit of a quandary. He was going to go home early today, which sounded like way more fun than working. The only problem is this: each moment away from work increases the chances that this Scripting Guy will get sick. In fact, if he truly wants to live forever (and he does), he should stay late and work overtime each night. And on weekends. And holidays. And ….

Hmmm …. Maybe those researchers should recheck their calculations. After all, it’s quite possible that putting in long hours and skipping vacations don’t make you live forever; they just make it seem like you’ve lived forever.

But don’t worry about that, either: we’ll just go ask Peter Costantini, the oldest living Scripting Guy. Peter should know; after all, he pretty much has lived forever.

Comments (40)

  1. Anonymous says:

    I would like to replace all the number on the left side of the underscore with blank space:
    I am suing the following and it does not work; any help is appreciated.
    (get-content D:TempTest1.txt) | foreach-object {$_ -replace ‘*_’, ‘_’} | set-content D:TempTest1.txt

  2. Putting this to good use.

  3. Anonymous says:

    Nevertheless is good example.

    Let’s say at the end of each line there are some white spaces.

    How we can make use of trim as these arrays contains reserved characters?

  4. Anonymous says:

    New to powershell… I need to remove the first 10 characters from every line within a text file (we'll call it chapter.txt). This is what I have:






    I need them to look like:






    Any way to do this with powershell? Or do I need to explore other methods like unix commands?

  5. Anonymous says:


    $lines = @()

    $text = Get-Content -Path .chapter.txt

    $text | %{ $lines += $_.SubString(10,$_.Length-10) }

    Set-Content -Path .NewChapter.txt -Value $lines


  6. jrv says:

    @kurninja – you are a ninja.  Roll with it.

    Ha! Ha!  You need to learn some WIndows.  The error is absolutel;y clear.  You cannot use a file that is in use.  It is just like a ninja cannot cut the air with a dull knife.  A sharp knife and a less than dull attitude will go far towards solving your existential dillema.

    None of what i have written is intended to be funny.  It is offered to the less than humble student in the most serious of mind.  It is the sound of one mind clapping.



  7. Matt B. says:

    Do I have to create a new line for each character I'd like to replace?  For example, if I have < and > and " I'd like to replace, do I have to have three lines each with a different replace operation?

  8. sudharsan says:

    Nice blog !! One problem i get is, when i use select-string after get-content the lengthier lines are automatically cut in 2 lines (It automatically inserts a new line char after the width of the screen) . And do powershell or any dll available which is as effecient as sed, awk in unix ??

  9. Ukraine Guy says:

    A very common problem with Windows explorer is reported on all Windows help forums. I've seen people complaining about problem with long path files deletion.

    Some common problems with Windows Explorer people talk about:

    – Doesn't allow to delete files with long path names

    – Pops up error while deleting unwanted files or unnecessary files

    – Errors like: Access denied, sharing violation, source in use etc.

    I've found a very simple but smart solution for all these above mentioned common problems. A very simple but powerful tool to overcome these problems. Everyone who plays with the files must have this tool. Its compatible with all versions of Microsoft Windows.


  10. DerekBez says:

    I like it!  Thanks.

    Could this technique be tweaked to work with large files?  I have a 200MB data file with dodgy characters (eg: commas and pipes) I need to strip about before I can reliable turn it into a csv for further processing.

    First time I tried your suggested basic bit of code above it eventually bombed out with an out-of-memory error.  I'm trying again now with a "-readcount 1000"…

    (I am a PowerScript absolute newbie, but keen it pick it up.)

    <time passes>

    …so 15 minutes later it had got 59.86% of the way through the file, and stopped with:

    Set-Content : Exception of type 'System.OutOfMemoryException' was thrown.

    So it would seem it doesn't like files over about 100MB.  Can you suggest any alternatives or additional parameters that might  do the trick?


  11. test says:

    this is a test. let's see if it works!

  12. unbob says:

    The regex class has a static method called Escape.  To get the escaped version of a string (assuming you want to escape characters indiscriminately) use [regex]::Escape($stringToBeEscaped).  Of course, eventually you'll want to use the full power of regular expressions, you'll learn the syntax and you'll know what needs escaping without thinking too hard about it.  Even then, [regex]::Escape can come in handy from time to time.

  13. jvrao says:

    Very good explain,..

    Could you explain about all regular expressions here.. thanks

  14. jvrao says:

    Very good explain..

    could you provide the example to replace the string from all the text file under the folder.. thanks

  15. Tugberk says:

    I did this for a *.doc file; and after doing so, LibreOffice can't open the *.doc file claiming it is damaged.


  16. I got a request please help says:

    how can i remove the singe quote from start and end of the line

    for example i got a text file called test.txt and in that i got 'user@contoso.com' and i want to remove the single quote from start or end

    Please help

  17. LadyOfTheLAN says:

    I like the stories – It ads to the fun of learning this stuff – and shows you have fun with it.

    Personally I find Powershell a lot of fun to work with.

    Keep up the good work!

  18. suma says:

    How to use replace many times in foreach loop

    Eg: I have

    $data =(Get-Content  input.txt)

    foreach($line in $data)

    {   $_ -replace ' NULL', ' '

       $_ -replace ' ', 'RM '

       $_ -replace ' |', ' '

       $_ -replace 'DM', 'DsM'

       $_ -replace 'Cm', 'RM'

       $_ -replace '0M', 'GM'  } | Set-Content 123.ps1.

    For each line line in input file i need to replace with  many strings.

  19. ML49448 says:

    Would it be possible to replace a character with a NULL character.

    I want to remove commas from a file and replace with nothing


    Michael, Lastname (Michael command space Lastname)


    Michael Lastname  (Michaell space lastname)



  20. jrv says:

    @Michael.  A null is not a space and a null will break a text file.

  21. Yann says:

    Well I have the same request… Can someone provide the solution ?

    How to use replace many times in foreach loop

    Eg: I have

    $data =(Get-Content  input.txt)

    foreach($line in $data)

    {   $_ -replace ' NULL', ' '

      $_ -replace ' ', 'RM '

      $_ -replace ' |', ' '

      $_ -replace 'DM', 'DsM'

      $_ -replace 'Cm', 'RM'

      $_ -replace '0M', 'GM'  } | Set-Content 123.ps1.

    For each line line in input file i need to replace with  many strings.

  22. jrv says:

    @suma – Hint:

    $_.Replace(' NULL', ' ').Replace(' ','RM ').Replace('|','')

  23. raviraj says:

    Thank you very much.

  24. Ava says:


    I need to campare two differnt text and find same line and replace with each other ???

    such 2 line on 2 text :

    text 1 : $SITELANG[“pagetop.title”] = “LOGO”;// Not in use

    text 2 :$SITELANG[“pagetop.title”] = “LOGO”;

    same line ,,,replace line in text 2 with same line text 1.

  25. pkj says:

    How to check if a string contain a special character?

  26. Ath3na says:

    Awesome article. You make things so easy to understand. Thanks

  27. Beginner3 says:

    How can I multiple (1000) files with different texts?
    example: the file1, file2, file3 has text "sample"
    need to change each file with sample1, sample2, sample3

    Any suggestions?

  28. Help says:

    @PowerShellPleaseHelp, Since @jrv wasn’t helpful at all, here is this. The Get-Content command opens the file to read it and the Set-Content command cannot write to an open file, so it fails. If you place parentheses around the Get-Content command it will
    open the file, read it, then close it. Then the Set-Content command will work. So your Get-Content command needs to be in parentheses. It will look like this:

    (Get-Content FILEPATH) | …

  29. Stroller says:

    very good, but I want to replace the for TT do i double them?

  30. Stroller says:

    Doh! should tested that first! yes you double them 😉

  31. BJ says:

    Thanks for a very good blog! How would the code look like if you have a folder with multiple files where you want to change a word inside all the files?

  32. Ganesh says:

    How to Find and replace if text is like this ?

    This is the Version L"{dffd56-dsf55-dfdsf5-545a}"

  33. CasE sensitive says:

    Running Windows 8.1, how do I accomplish search and replace with case sensitive text?

  34. Mike P says:

    Love your articles.
    What if you need to escape a character that’s within quotes? For example, my replace string is: AssemblyVersion("1.2.*"). This works: -replace "1.2.*", "1.2.3" but is to broad. As such, I’ve tried: -replace ‘AssemblyVersion("1.2.*")’,’AssemblyVersion("1.2.3")’
    without success. Have I got my quoting all wrong and/or is escaping handled differently when the string is quoted?

  35. Kishore says:

    How to search a string in updating files in directory please provide the script

  36. KMSigma says:

    This is a great example and I’m using it to cleanup some entries within some of my IIS logs. However, many of the logs are over 300 MB flat files. When running, the PowerShell process routinely takes up over 1GB of Memory (as it reads the entire file into
    memory). Is there a more efficient way to handle this?

  37. KMSigma says:

    After some tinkering, I decided to use:
    $Source | Get-Content | ForEach-Object { $_ -replace ‘[RegexString]’, ‘[ReplaceString]’ | Out-File -FilePath $Destination -Append -Encoding ascii }
    This prevents PowerShell from reading the entire file at once, but it still needs to churn through each line.
    It’s now running with less than 200 MB memory, but it’s still a hog when it comes to CPU utilization. I’m not sure that there’s a way to get by that particular issue.
    If someone else has a suggestion, I’m all ears, but I thought that I’d share what I’ve found.

  38. MJ Ross says:

    What am I doing wrong here? I just need to replace the "shared_buffers = 32MB value to 256MB?

    (Get-Content F:hpUCMDBDataFlowProbepgsqldatapostgresql.conf)
    |ForEach-Object {$_ -replace "shared_buffers = 32MB", "shared_buffers = 256MB"}
    |Set-Content F:hpUCMDBDataFlowProbepgsqldatapostgresql.conf

    Thank you for any help you could offer?

  39. Thomas P Gould says:

    Hey Scripting guy – This was a great forum. I am trying to apply this knowledge to a little more complex scenario. How would i do something along these lines when i would need to replace multiple invalid characters in a string.

    Lets say i have a variable $StringWithInvalidChars = "This is an invalid character, i think?"

    How would i go about replacing the , with , and also the ? with ? since both are invalid characters and is "technically" an invalid character. At first i thought this would be easy lets just do a loop that looks something like this:

    $arrInvalidCharacters = ‘$’,'( )’,’*’,’+’,’.’,'[‘,’]’,’?’,”,’/’,’^’,'{‘,’}’,’|’,’,’
    foreach ($InvChar in $arrInvalidCharacters)
    $VariableWithOutInvalidChars = $VariableWithInvalidChars | ForEach-Object {$_ -replace "$InvChar","$InvChar"}

    But this will replace the first invalid character and none of the rest. Is there a way to look past an escape character only if is being used as an escape character, otherwise replace it as an escape character?

Skip to main content