使用PowerShell正确读取UTF-8文件

时间:2014-04-01 14:49:37

标签: powershell encoding utf-8

以下情况:

  • PowerShell脚本使用UTF-8编码创建文件
  • 用户可能编辑或不编辑文件,可能会丢失BOM,但应将编码保持为UTF-8,并可能更改行分隔符
  • 相同的PowerShell脚本读取文件,添加更多内容并将其全部作为UTF-8写回同一文件
  • 这可以多次迭代

Get-ContentOut-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

运行几次后,应在文件的开头添加新的部分,不应以任何方式更改现有内容(当前丢失换行符),并且不应在末尾添加其他新行。文件(似乎有时会发生)。

相反,第二次运行会给我一个错误。

3 个答案:

答案 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!