以下情况:
Get-Content
和Out-File -Encoding UTF8
我无法正确阅读。它之前编写的BOM(将其放入内容,破坏我的解析正则表达式)的绊脚石,不使用UTF-8编码甚至删除原始内容部分中的换行符。
我需要一个能够读取任何UTF-8编码文件的函数,忽略并删除BOM而不修改内容。我该怎么用?
更新
我添加了一个小小的测试脚本,显示了我尝试做什么以及发生了什么。
# Read data if exists
$data = ""
$startRev = 1;
if (Test-Path test.txt)
{
$data = Get-Content -Path test.txt
if ($data -match "^[0-9-]{10} - r([0-9]+)")
{
$startRev = [int]$matches[1] + 1
}
}
Write-Host Next revision is $startRev
# Define example data to add
$startRev = $startRev + 10
$newMsgs = "2014-04-01 - r" + $startRev + "`r`n`r`n" + `
"Line 1`r`n" + `
"Line 2`r`n`r`n"
# Write new data back
$data = $newMsgs + $data
$data | Out-File test.txt -Encoding UTF8
运行几次后,应在文件的开头添加新的部分,不应以任何方式更改现有内容(当前丢失换行符),并且不应在末尾添加其他新行。文件(似乎有时会发生)。
相反,第二次运行会给我一个错误。
答案 0 :(得分:24)
如果该文件应该是UTF8,为什么不尝试读取它解码UTF8:
Get-Content -Path test.txt -Encoding UTF8
答案 1 :(得分:4)
真的是JPBlanc是对的。如果您希望将其读作UTF8,请在读取文件时指定。
另一方面,你在这里用[String] + [String]的东西丢失格式。更不用说你的正则表达式匹配不起作用。查看正则表达式搜索更改,以及对$ newMsgs所做的更改,以及我将数据输出到文件的方式。
# Read data if exists
$data = ""
$startRev = 1;
if (Test-Path test.txt)
{
$data = Get-Content -Path test.txt #-Encoding UTF8
if($data -match "\br([0-9]+)\b"){
$startRev = [int]([regex]::Match($data,"\br([0-9]+)\b")).groups[1].value + 1
}
}
Write-Host Next revision is $startRev
# Define example data to add
$startRev = $startRev + 10
$newMsgs = @"
2014-04-01 - r$startRev`r`n`r`n
Line 1`r`n
Line 2`r`n`r`n
"@
# Write new data back
$newmsgs,$data | Out-File test.txt -Encoding UTF8
答案 2 :(得分:2)
Get-Content似乎根本不处理没有BOM的UTF文件(如果省略Encoding-flag)。 System.IO.File.ReadLines似乎是另一种选择,例如:
PS C:\temp\powershellutf8> $a = Get-Content .\utf8wobom.txt
PS C:\temp\powershellutf8> $b = Get-Content .\utf8wbom.txt
PS C:\temp\powershellutf8> $a2 = Get-Content .\utf8wbom.txt -Encoding UTF8
PS C:\temp\powershellutf8> $a
ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ <== This doesnt seem to be right at all
PS C:\temp\powershellutf8> $b
ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ
PS C:\temp\powershellutf8> $a2
ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ
PS C:\temp\powershellutf8>
PS C:\temp\powershellutf8> $c = [IO.File]::ReadLines('.\utf8wbom.txt');
PS C:\temp\powershellutf8> $c
ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ
PS C:\temp\powershellutf8> $d = [IO.File]::ReadLines('.\utf8wobom.txt');
PS C:\temp\powershellutf8> $d
ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ <== Works!