PowerShell pitfalls: reading text from file using get-content
I had a really strange effect in PowerShell that puzzled me for hours!
I have the following script:
$a = @' One Two '@ $a $p = [regex]"One" $p.Replace($a, "OneReplaced")$b = get-content -path templ.txt $b $q = [regex]"One" $q.Replace($b, "OneReplaced")
And a file templ.txt containing the following text:
One Two
When I execute the script I get the following output:
One Two OneReplaced Two One Two OneReplaced Two
So what happens:
I initialize a variable $a with two lines of text: line 1: One, line 2: Two. When I display variable $a it shows One and Two on two seperate lines. I now replace One with OneReplaced. Output of the replacement is two lines of text. Line 1: OneReplaced, line 2: Two.
Everything ok so far.
I now read the contents of variable $b from the file templ.txt. This file contains two lines of text: line 1: One, line 2: Two. When I display variable $b it shows One and Two on two seperate lines. I now replace One with OneReplaced. Output of the replacement is ONE LINE of text: OneReplaced Two.
This is not what I expected.
After a lot of debugging I found out why this happened. When you do $b = get-content -path templ.txt you don't get a string back, but an object array. You can see that when you do: (get-content -path templ.txt).GetType(), this displays:
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array
If you inspect the Object[] variable $b, you see that $b[0] = "One" and $b[1] = "Two".
When the command $q.Replace($b, "OneReplaced") is executed, the variable $b of type Object[] is cast to a string. This cast combines the string objects in the Object[] by appending them with a space in the middle.
So what is the simple solution to all this: when reading the content, join all lines with a newline, as in the following code line:
$b = [string]::join([environment]::newline, (get-content -path templ.txt))
Such a pity that this costed me 4 hours, I thought it was in the regular expression replacement:-(
But the good thing is that I can now solve that nasty bug in my Template Engine using PowerShell expressions.