我想将文件模板加载到变量中,修改变量中的数据,并将修改后的模板输出到变量的新位置。
问题是PowerShell正在从我的模板中删除换行符。
输入文件(模板文件)具有Unix行结尾,这也是输出所必需的,因为修改版本的接收者是基于Unix的系统。
我有以下代码,结果是连续的单行:
[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
输入模板:
#!/bin/sh
myvar="<REPLACE_ME>"
echo "my variable: $myvar"
exit 0
导致:
#!/bin/sh myvar="Foo Bar" echo "my variable: $myvar" exit 0
在我看来,某个地方LF
被一个简单的空格所取代。最后,在脚本末尾添加了CR LF
,模板文件中没有该文件。
如何保留行结尾并防止在最终脚本中添加更多(CR LF
)错误的行结尾?
答案 0 :(得分:6)
对于$replacement
变量,您实际上不需要指定类型[string]
,PowerShell会从赋值中推断出来。
对于$template
变量,[string]
实际上是错误的。默认情况下,Get-Content
将为您提供一个字符串数组(即行),而不是一个字符串。
但实际上你甚至不想把输入分成第一行。当Set-Content
或Out-File
将数组视为输入时,他们会将其与空格连接。
使用-Raw
使Get-Content
将整个文件作为一个字符串返回,这样行结尾(如Linux文件的LF
)将保持原样。
$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将使用BOM保存所有UTF-8文件。如果您不想这样,则必须使用其他实用程序来编写文件:
$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)
注意:
-replace
)以静默方式对数组进行操作。 $x -replace "search", "replacement"
将对 $ x 的每个成员执行替换操作,无论是单个字符串还是其中的数组。答案 1 :(得分:0)
使用-分隔符“`n” 选项代替 -raw 。 -raw 选项将整个内容读取/返回为单个字符串,尽管它保留换行符,但是如果您需要操纵内容(例如,跳过标题第一行或跳过空白行等。
获取内容-背景信息:
默认情况下,Get-Content
cmdlet逐行读取并返回内容,这意味着如果您通过管道传输Set-Content
或Add-Content
来立即写每行(正在读取)到输出文件中-换行符将按预期保留并写入,例如:
Get-Content $inputFile | Set-Content $outputFilePath
但是,如果将整个内容(读取的内容)存储到$ variable中,则会收到一个没有任何分隔符/分隔符的字符串数组(默认情况下),这意味着您会丢失换行符,但是,读取文件(使用Get-Content
)时,您可以使用-delimiter
选项指定换行符,例如:
Get-Content -Delimiter "`n" $fileToRead
HTH。
答案 2 :(得分:0)
我使用的是Get-Content-Tail
,它不允许您同时指定-Raw
,但是我对Out-String
确实很幸运。因此,就您而言:
$template = Out-String -InputObject $( Get-Content -Path "$pwd\template.sh" -Encoding UTF8 -Raw)
或者也许,如果您关心尾巴:
$template = Out-String -InputObject $(Get-Content -Path "$pwd\template.sh" -tail 4)