2012-02-02 13 views
23

मैं वर्तमान में कुछ खोज पर काम कर रहा हूं और ऑपरेशन को प्रतिस्थापित कर रहा हूं जिसे मैं पावरहेल का उपयोग करके स्वचालित करने की कोशिश कर रहा हूं। दुर्भाग्यवश मैंने कल पहचाना कि हमारे कोडबेस (यूटीएफ 8 और एएससीआईआईआई) में अलग-अलग फ़ाइल एन्कोडिंग हैं। चूंकि हम इन खोजों को कर रहे हैं और एक अलग शाखा में संचालन को प्रतिस्थापित कर रहे हैं, इसलिए मैं इस चरण में फ़ाइल एन्कोडिंग नहीं बदल सकता।पावरशेल आउट-फ़ाइल: एन्कोडिंग परिवर्तनों को रोकें

यदि मैं निम्नलिखित पंक्तियां चला रहा हूं तो यह सभी फ़ाइलों को यूसीएस -2 लिटिल ईंडियन में बदल देता है, भले ही मेरा डिफ़ॉल्ट पावरहेल एन्कोडिंग आईएसओ -885 9 -1 (पश्चिमी यूरोपीय (विंडोज)) पर सेट हो।

$content = Get-Content $_.Path 
$content -replace 'myOldText' , 'myNewText' | Out-File $_.Path 

क्या शक्तियों को फ़ाइल के एन्कोडिंग को बदलने से रोकने का कोई तरीका है?

क्या मैं हल करने के लिए इस मूल फ़ाइल के कूट प्राप्त करने की कोशिश करने के लिए है किया है यह byte order mark है पढ़ने का प्रयास पढ़ने और -Encoding के रूप में यह का उपयोग करके:

उत्तर

31

Out-File एक डिफ़ॉल्ट एन्कोडिंग जब तक -Encoding पैरामीटर के साथ ओवरराइड है पैरामीटर मान

यहां एक उदाहरण है पाठ फ़ाइल पथों का एक गुच्छा संसाधित करना, मूल एन्कोडिंग प्राप्त करना, सामग्री को संसाधित करना और इसे मूल के एन्कोडिंग के साथ फ़ाइल में लिखना।

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 
} 

अद्यतन यहाँ StreamReader वर्ग का उपयोग कर मूल फ़ाइल एन्कोडिंग होने का एक उदाहरण है। उदाहरण फ़ाइल के पहले 3 बाइट्स को पढ़ता है ताकि CurrentEncoding संपत्ति अपने आंतरिक बीओएम पहचान दिनचर्या के परिणामस्वरूप सेट हो जाए।

http://msdn.microsoft.com/en-us/library/9y86s1a9.aspx

detectEncodingFromByteOrderMarks पैरामीटर द्वारा एन्कोडिंग धारा के पहले तीन बाइट्स को देखकर पता लगाता है। यह स्वचालित रूप से यूटीएफ -8, छोटे-एंडियन यूनिकोड, और बड़े-एंडियन यूनिकोड टेक्स्ट को पहचानता है यदि फ़ाइल उपयुक्त बाइट ऑर्डर अंकों से शुरू होती है। अन्यथा, यूटीएफ 8 एन्कोडिंग का उपयोग किया जाता है। अधिक जानकारी के लिए एन्कोडिंग। गेटप्र्रीमबल विधि देखें।

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 
+0

मैं पहले से ही इसके बारे में सोचा, लेकिन एक आसान तरीका होना चाहिए, यह नहीं करना चाहिए? लेकिन यह अब मेरे लिए काम करता है। धन्यवाद एंडी! – Pete

+2

@Pete आपको एन्कोडिंग प्राप्त करने जा रहे हैं। कोई cmdlet नहीं है जो इसे आपके लिए प्राप्त करेगा। मैंने अपना जवाब एक अलग दृष्टिकोण जोड़ दिया। दोनों तरीकों से बीओएम पहचान का उपयोग करें। –

+0

'सेट-कंटेंट -पथ BOM_Utf32.txt -Value $ null -Eccoding UTF32' लिखता है _UTF-32, little-endian_ BOM i.e.' एफएफ एफई 00 00' बाइट अनुक्रम। हालांकि, 'गेट-फाइल एन्कोडिंग' कार्य 'यूनिकोड' लौटाता है। दूसरी तरफ, '00 00 एफई एफएफ' बाइट अनुक्रम' यूटीएफ 32' के रूप में पहचाना जाता है लेकिन [यूनिकोड कंसोर्टियम] के अनुसार (http://unicode.org/faq/utf_bom.html#BOM) यह _UTF-32 है, बड़ा-एंडियन_ बीओएम। क्या मै गलत हु? त्रुटि कहां है? – JosefZ

संबंधित मुद्दे