I want to load a file template into a variable, modify data within the variable and output the modified template to a new location from the variable.
The issue is that PowerShell is removing newlines from my template.
The input file (template file) has Unix line endings which are also required for output since the recipient of the modified version is a Unix-based system.
I have the following code which results into a concatted one-liner:
[String] $replacement = "Foo Bar"
[String] $template = Get-Content -Path "$pwd\template.sh" -Encoding UTF8
$template = $template -replace '<REPLACE_ME>', $replacement
$template | Set-Content -Path "$pwd\script.sh" -Encoding UTF8
Having the template input:
#!/bin/sh
myvar="<REPLACE_ME>"
echo "my variable: $myvar"
exit 0
Resulted into:
#!/bin/sh myvar="Foo Bar" echo "my variable: $myvar" exit 0
It appears to me that somewhere LF
where replaced by one simple whitespace. Finally at the end of the script there is an added CR LF
which was not present in the template file.
How do I preserve the line endings and prevent adding further (CR LF
) wrong line endings to the final script?
For the $replacement
variable, you don't really need to specify the type [string]
, PowerShell will infer that from the assignment.
For the $template
variable, [string]
is actually wrong. By default, Get-Content
will give you an array of strings (i.e. lines) instead of one string.
But in fact you don't even want to split the input into lines in the first place. When Set-Content
or Out-File
see an array as their input, they will join it with spaces.
Using -Raw
makes Get-Content
return the entire file as one string, this way also the line endings (like LF
for Linux files) will stay the way they are.
$replacement = "Foo Bar"
$template = Get-Content -Path "$pwd\template.sh" -Encoding UTF8 -Raw
$template = $template -replace '<REPLACE_ME>', $replacement
Set-Content -Path "$pwd\script.sh" -Value $template -Encoding UTF8
PowerShell will save all UTF-8 files with a BOM. If you don't want that, you must use a different utility to write the file:
$UTF8_NO_BOM = New-Object System.Text.UTF8Encoding $False
$replacement = "Foo Bar"
$template = Get-Content -Path "$pwd\template.sh" -Encoding UTF8 -Raw
$template = $template -replace '<REPLACE_ME>', $replacement
[System.IO.File]::WriteAllText("$pwd\script.sh", $template, $UTF8_NO_BOM)
Notes:
-replace
) silently operate on arrays. $x -replace "search", "replacement"
will perform a replace operation on every member of $x, be that a single string or an array of them.