首页 文章

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

提问于
浏览
11

以下情况:

  • PowerShell脚本使用UTF-8编码创建文件

  • 用户可能编辑也可能不编辑文件,可能会丢失BOM,但应将编码保持为UTF-8,并可能更改行分隔符

  • 相同的PowerShell脚本读取文件,添加更多内容并将其全部作为UTF-8写回同一文件

  • 这可以多次迭代

使用 Get-ContentOut-File -Encoding UTF8 时,我无法正确读取它 . 这是它之前编写的BOM(将其放入内容,破坏我的解析正则表达式)的绊脚石,不使用UTF-8编码甚至删除原始内容部分中的换行符 .

我需要一个能够读取任何UTF-8编码文件的函数,忽略并删除BOM而不修改内容 . 我该怎么用?

Update

我添加了一个小测试脚本,显示我正在尝试做什么以及发生了什么 .

# 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 回答

  • 2

    如果该文件应该是UTF8,为什么不尝试读取它解码UTF8:

    Get-Content -Path test.txt -Encoding UTF8
    
  • 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
    
  • 22

    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!
    

相关问题