我想这样做:
$content = get-content "test.html"
$template = get-content "template.html"
$template | out-file "out.html"
其中template.html包含
<html>
<head>
</head>
<body>
$content
</body>
</html>
和test.html包含:
<h1>Test Expand</h1>
<div>Hello</div>
我在out.html的前两个字符中得到了奇怪的字符:
��
并且内容未展开。
如何解决这个问题?
答案 0 :(得分:3)
对于&#34;奇怪的字符&#34;,它们可能是BOM(字节顺序标记)。使用-Encoding
时,使用Out-File
参数明确指定输出编码,例如:
$Template |Out-File out.html -Encoding UTF8
对于字符串扩展,您需要明确告诉powershell这样做:
$Template = $Template |ForEach-Object {
$ExecutionContext.InvokeCommand.ExpandString($_)
}
$Template | Out-File out.html -Encoding UTF8
答案 1 :(得分:3)
使用以下解决方案补充Mathias R. Jessen's helpful answer:
# Explicitly read the input files as UTF-8, as a whole.
$content = get-content -raw -encoding utf8 test.html
$template = get-content -raw -encoding utf8 template.html
# Write to output file using UTF-8 encoding *without a BOM*.
[IO.File]::WriteAllText(
"$PWD/out.html",
$ExecutionContext.InvokeCommand.ExpandString($template)
)
get-content -raw
(PSv3 +)将中的文件作为整体读入单字符串(而不是数组 of strings,line by line),虽然内存密集程度更高,但速度更快。对于HTML文件,内存使用不应该是一个问题。
$(...)
),扩展仍然可以正常运行。 get-content -encoding utf8
确保输入文件被解释为使用UTF-8字符编码,这在当今的网络世界中很常见。
单个$ExecutionContext.InvokeCommand.ExpandString()
调用足以执行模板扩展。
Out-File -Encoding utf8
总是会创建一个带有伪BOM的文件,这是不受欢迎的。
相反,使用 [IO.File]::WriteAllText()
,利用.NET Framework 默认创建UTF-8编码文件而不 BOM << /强>
$PWD/
之前使用out.html
,这是确保文件在 PowerShell 的当前位置(目录)中编写所必需的;不幸的是,.NET Framework认为当前目录是而不是与PowerShell同步。最后,强制性安全警告:仅在您信任的输入上使用此扩展技术,因为任意嵌入式命令可能会被执行。
PowerShell的Out-File
,>
和>>
默认使用UTF-16 LE字符编码BOM (byte-order mark)(如上所述,“奇怪的字符”)。
虽然 Out-File -Encoding utf8
允许创建UTF-8输出文件,但是
PowerShell 总是在输出文件中添加一个3字节的pseudo-BOM ,其中一些实用程序,特别是那些具有Unix遗产的实用程序存在问题 - 所以你仍然> em>得到“奇怪的人物”(虽然不同)。
如果您希望更像PowerShell的方式来创建无BOM的UTF-8文件,
请参阅我的this answer,其中定义了一个Out-FileUtf8NoBom
函数,该函数以其他方式模拟Out-File
的核心功能。
相反,在读取文件上,您必须使用Get-Content -Encoding utf8
来确保无BOM的UTF-8文件被识别。
如果没有UTF-8伪BOM,Get-Content
会假定该文件使用系统的旧版代码页指定的单字节扩展ASCII编码 (例如,英语系统上的Windows-1252,PowerShell称之为Default
的编码。)
请注意,虽然仅限Windows的编辑器(如记事本)创建带有伪BOM的UTF-8文件(,如果您明确选择保存为UTF-8;默认是遗留代码页编码,“ANSI”),越来越受欢迎的跨平台编辑器,例如Visual Studio Code,Atom和Sublime Text,默认情况下不在创建文件时使用伪BOM。