Out-File
có một mã hóa mặc định trừ khi overriden với -Encoding
tham số:
gì tôi đã thực hiện để giải quyết này là cố gắng để có được mã hóa các tập tin gốc bằng cách đọc cố gắng đọc nó byte order mark và sử dụng nó như là -Encoding
Giá trị tham số.
Dưới đây là một ví dụ xử lý một loạt các đường dẫn tệp văn bản, nhận được mã hóa ban đầu, xử lý nội dung và ghi nó trở lại tệp với mã hóa ban đầu.
function Get-FileEncoding {
param ([string] $FilePath)
[byte[]] $byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $FilePath
if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf)
{ $encoding = 'UTF8' }
elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff)
{ $encoding = 'BigEndianUnicode' }
elseif ($byte[0] -eq 0xff -and $byte[1] -eq 0xfe)
{ $encoding = 'Unicode' }
elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff)
{ $encoding = 'UTF32' }
elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76)
{ $encoding = 'UTF7'}
else
{ $encoding = 'ASCII' }
return $encoding
}
foreach ($textFile in $textFiles) {
$encoding = Get-FileEncoding $textFile
$content = Get-Content -Encoding $encoding
# Process content here...
$content | Set-Content -Path $textFile -Encoding $encoding
}
Cập nhật Dưới đây là một ví dụ về việc mã hóa tập tin ban đầu bằng cách sử dụng lớp StreamReader. Ví dụ này đọc 3 byte đầu tiên của tệp để thuộc tính CurrentEncoding
được đặt dựa trên kết quả của thường trình phát hiện BOM nội bộ của nó.
http://msdn.microsoft.com/en-us/library/9y86s1a9.aspx
Tham số detectEncodingFromByteOrderMarks phát hiện mã hóa bởi nhìn vào ba byte đầu tiên của dòng. Tự động nhận dạng UTF-8, Unicode nhỏ gọn và văn bản Unicode lớn nhất nếu tệp bắt đầu bằng các dấu thứ tự byte thích hợp. Nếu không, UTF8Encoding được sử dụng. Xem phương thức Encoding.GetPreamble để biết thêm thông tin .
http://msdn.microsoft.com/en-us/library/system.text.encoding.getpreamble.aspx
$text = @"
This is
my text file
contents.
"@
#Create text file.
[IO.File]::WriteAllText($filePath, $text, [System.Text.Encoding]::BigEndianUnicode)
#Create a stream reader to get the file's encoding and contents.
$sr = New-Object System.IO.StreamReader($filePath, $true)
[char[]] $buffer = new-object char[] 3
$sr.Read($buffer, 0, 3)
$encoding = $sr.CurrentEncoding
$sr.Close()
#Show the detected encoding.
$encoding
#Update the file contents.
$content = [IO.File]::ReadAllText($filePath, $encoding)
$content2 = $content -replace "my" , "your"
#Save the updated contents to file.
[IO.File]::WriteAllText($filePath, $content2, $encoding)
#Display the result.
Get-Content $filePath
Nguồn
2012-02-02 23:35:16
Tôi đã nghĩ về điều đó nhưng phải có một cách dễ dàng hơn, không phải nó? Nhưng điều đó làm việc cho tôi bây giờ. Cảm ơn Andy! – Pete
@Pete Bạn sẽ phải lấy mã hóa. Không có lệnh ghép ngắn nào cho bạn. Tôi đã cập nhật câu trả lời của mình bằng cách thêm một cách tiếp cận khác. Cả hai cách đều sử dụng tính năng phát hiện BOM. –
'Set-Content -Path BOM_Utf32.txt -Giá trị $ null -Kích hoạt UTF32' ghi _UTF-32, bit-endian_ BOM nghĩa là chuỗi byte' FF FE 00 00'. Tuy nhiên, hàm 'Get-FileEncoding' trả về' Unicode'. Mặt khác, chuỗi byte '00 00 FE FF' được nhận dạng là' UTF32' nhưng theo [Unicode Consortium] (http://unicode.org/faq/utf_bom.html#BOM) đây là _UTF-32, big-endian_ BOM. Liệu tôi có sai? Lỗi đâu rồi? – JosefZ