Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserve newlines when concatenating or using heredoc in PowerShell

Tags:

powershell

Suppose I have the a document c:\temp\temp.txt with contents

line 1
line 2

and I create the following function

PS>function wrapit($text) {
@"
---Start---
$text
---End---
"@
}

Then running PS> wrapit((Get-Content c:\temp\temp.txt))

will output

---Start---
line 1 line 2
---End---

How do I preserve newlines? Appending versus interpolating doesn't help.

I found this related question, but here they are using a string array. I am using a single string which has newline characters in it (you can see them if you output the string directly from inside the function without concatenating and $text | gm confirms I'm working with a string, not an array). I can do all the string parsing in the world to hammer it into place, but that seems like I'd be banging a square peg in a round hole. What is the concept that I'm missing?

like image 680
George Mauer Avatar asked Nov 13 '12 04:11

George Mauer


2 Answers

A simple way to do what you want is:

wrapit((Get-Content c:\temp\temp.txt | out-string))

Now the explanation: Here-strings @"" just behave like strings "" and the result is due to the PowerShell behaviour in variables expansion. Just try:

$a = Get-Content c:\temp\temp.txt
"$a"

Regarding your comment:

$a | Get-Member
TypeName: System.String
...

But

Get-Member -InputObject $a
TypeName: System.Object[]
...

The first answer is OK (it receives strings). It just does not repeat System.string each time. In the second it receive an array as parameter.

like image 89
JPBlanc Avatar answered Sep 30 '22 12:09

JPBlanc


Son of a...

Upon investigation it seems that Get-Content returns a string array. Which is of course coerced to a string by default by joining on the default character ' '.

What is really puzzling is why the results are coerced by get-member to a string. Anyone know why that would happen? The issue wasn't obvious until I explicitly checked Get-Type

In any case, the solution was to read the file using [system.io.file]::ReadAllText('c:\temp\temp.txt') over Get-Content

like image 24
George Mauer Avatar answered Sep 30 '22 14:09

George Mauer