在PowerShell中使用内容集多个文件保持相同的编码

时间:2019-05-14 14:46:47

标签: powershell encoding

我正在尝试编写一个脚本,该脚本用于将应用程序从服务器迁移到服务器和/或从一个驱动器号迁移到另一个驱动器号。我的目标是从一个位置复制目录,将其移动到另一位置,然后运行脚本以编辑旧主机名,IP地址和驱动器号的所有实例,以在新主机名,IP地址和驱动器号上反映新的主机名,IP地址和驱动器号。新服务器。看来正是这样:

ForEach($File in (Get-ChildItem $path\* -Include *.xml,*.config -Recurse)){
    (Get-Content $File.FullName -Raw) -replace [RegEx]::Escape($oldhost),$newhost `
                                 -replace [RegEx]::Escape($oldip),$newip `
                                 -replace "$olddriveletter(?=:\Application)",$newDriveLetter | 
     Set-Content $File.FullName -NoNewLine
}

我遇到的一个问题是文件都具有不同类型的编码。一些ANSI,一些UTF-8,一些Unicode等。当我运行脚本时,它将所有内容另存为ANSI,然后我的应用程序无法工作。我知道如何添加encoding参数,但是有什么方法可以在每个文件上保持相同的编码,而无需编写脚本来指定目录中的每个文件以及每个文件具有的编码?

2 个答案:

答案 0 :(得分:1)

那将是困难的。 get-content不通过encoding属性是非常糟糕的。这是一个脚本,如果有签名,它会尝试获取编码。也许您可以先运行它并检查所有内容。但是某些Windows文件是unicode no bom。至少xml文件可以说编码。 get-childitem *.xml | select-string encoding可能有更好的方式来加载xml文件,请参见底部答案:Powershell: Setting Encoding for Get-Content Pipeline

# encoding.ps1
# https://stackoverflow.com/questions/3825390/effective-way-to-find-any-files-encoding
param([Parameter(ValueFromPipeline=$True)] $filename)
process {
  $reader = [IO.StreamReader]::new($filename, [Text.Encoding]::default,$true)
  $peek = $reader.Peek()
  $encoding = $reader.currentencoding
  $reader.close()
  [pscustomobject]@{Name=split-path $filename -leaf
                BodyName=$encoding.BodyName
            EncodingName=$encoding.EncodingName}
}
# end encoding.ps1


PS C:\users\me> get-childitem chinese16.txt | encoding

Name          BodyName EncodingName
----          -------- ------------
chinese16.txt utf-16   Unicode

类似的事情将使用xml文件中指示的编码,即使之前没有真正匹配。 (这也使xml很漂亮。)

PS C:\users\me> [xml]$xml = get-content file.xml
PS C:\users\me> $xml.save('file.xml')

答案 1 :(得分:0)

使用git二进制文件中的file.exe找出编码。 然后,使用if else语句将encoding参数添加到set-content行中。

ForEach($File in (Get-ChildItem $path\*)){
    $Content = Get-Content $File.FullName -Raw -replace [RegEx]::Escape($oldhost),$newhost `
                                 -replace [RegEx]::Escape($oldip),$newip `
                                 -replace "$olddriveletter(?=:\Application)",$newDriveLetter 
    $Encoding = file --mime-encoding $File
    $FullName = $File.FullName
    Write-Host "$FullName - $Encoding"
    if(-NOT ($Encoding -like "UTF")){
        Set-Content $Content -NoNewLine -Encoding UTF8
    }
    else {
        Set-Content $Content -NoNewLine 
    }
}

参考: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-content http://gnuwin32.sourceforge.net/packages/file.htm