我想将一个文件模板加载到一个变量中,修改变量中的数据,并将修改后的模板从变量输出到一个新位置。
问题是PowerShell正在从我的模板中删除换行符。
输入文件(模板文件)具有Unix行结尾,由于修改版本的接收者是基于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
)* 错误 * 的行尾?
4条答案
按热度按时间wixjitnu1#
对于
$replacement
变量,您实际上不需要指定[string]
类型,PowerShell将从赋值中推断该类型。对于
$template
变量,[string]
实际上是错误的,默认情况下,Get-Content
会给予你一个字符串数组(即行),而不是一个字符串。但实际上,你一开始就不想把输入拆分成行,当
Set-Content
或Out-File
看到一个数组作为它们的输入时,它们会用空格把它连接起来。使用
-Raw
可以使Get-Content
将整个文件作为一个字符串返回,这样行结束符(如Linux文件的LF
)也将保持原样。PowerShell将使用BOM保存所有UTF-8文件。如果您不希望这样,则必须使用其他实用程序写入该文件:
注:
-replace
)对数组执行静默操作。$x -replace "search", "replacement"
将对 $x 的每个成员执行替换操作,无论是单个字符串还是它们的数组。drkbr07n2#
使用**-delimiter“'n”选项,而不是-raw**。***-raw***选项将整个内容作为单个字符串读取/返回,尽管它保留了换行符,但如果您需要操作内容(例如跳过标题/第一行或跳过空行等),则该选项将毫无用处。
获取内容背景信息:
默认情况下,
Get-Content
cmdlet逐行读取并返回内容,这意味着如果您通过管道传输Set-Content
或Add-Content
以立即将每行(正在读取的)写入输出文件,则会保留换行符并按预期写入,例如:但是,如果存储整个内容(读入)变量(称为$variable),则变量将仅接收单个字符串数组,而不接收分隔符/定界符(默认情况下),这意味着在阅读文件时将丢失换行符(使用
Get-Content
)您可以使用-delimiter
选项来指定一个换行符('n),它将被保留并写入/存储到您的$变量中,例如:嗯。
nkoocmlb3#
我认为您需要将
-Raw
开关与Get-Content
一起使用,以便将文件作为单个字符串加载:要停止将Windows行尾添加到脚本末尾,我认为您需要使用以下.NET方法来编写文件:
默认情况下,PowerShell会尝试将您的输入转换为文件中每行的字符串数组。我认为由于Unix行尾,它没有成功地做到这一点,但随后会删除新的行字符。
在PowerShell 3.0中,我们现在有了一个新的动态参数Raw。指定后,Get-Content将忽略换行符,并在一个字符串中返回文件的全部内容。Raw是一个动态参数,仅在文件系统驱动器中可用。
vq8itlhq4#
我使用的是
Get-Content-Tail
,它不允许同时指定-Raw
,但我确实幸运地使用了Out-String
。或者,如果你关心尾巴: