2014-04-01 11 views
7

साथ सही ढंग से स्थिति के बाद:पढ़ें UTF-8 फ़ाइलें PowerShell

  • एक PowerShell स्क्रिप्ट UTF-8 एन्कोडिंग वाली फ़ाइल बनाता है
  • उपयोगकर्ता या फ़ाइल, संभवतः बीओएम खोने को संपादित नहीं हो सकता है, लेकिन UTF-8 के रूप में एन्कोडिंग रखना चाहिए, और संभवतः पंक्ति विभाजक
  • ही PowerShell स्क्रिप्ट फ़ाइल पढ़ता बदल रहा है, कुछ और अधिक सामग्री कहते हैं और के रूप में UTF-8 वापस एक ही फाइल को
  • यह दोहराया जा सकता है यह सब लिखते हैं कई बार

Get-Content और Out-File -Encoding UTF8 के साथ मुझे इसे सही तरीके से पढ़ने में समस्याएं हैं। यह बीओएम पर ठोकर खा रहा है, जिसने इसे लिखा है (इसे सामग्री में डालने, मेरे पार्सिंग रेगेक्स को तोड़ने), यूटीएफ -8 एन्कोडिंग का उपयोग नहीं करता है और मूल सामग्री भाग में लाइन ब्रेक भी हटा देता है।

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

अद्यतन

मैं पता चलता है कि मैं क्या करने की कोशिश कर रहा हूँ और क्या एक छोटे से परीक्षण स्क्रिप्ट को शामिल किया है बजाय होता है।

# 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 

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

इसके बजाए, दूसरा रन मुझे एक त्रुटि देता है।

+0

मैं पूरी एन्कोडिंग विषय के साथ महान नहीं कर रहा हूँ, लेकिन आप फिर से सुई बीओएम नहीं होती है, तो इसे हटा दिया जाता है, इसे ठीक से पढ़ने के लिए? मैं सवाल से थोड़ा उलझन में हूँ। आप यूटीएफ -8 बीओएम को क्यों हटाना चाहते हैं? –

+0

मेरा टेक्स्ट एडिटर बेवकूफ है और इसे हटा देता है। वैसे भी आप कभी नहीं जानते कि पाठ संपादक यूटीएफ -8 फाइलों के साथ क्या करते हैं। मेरी स्क्रिप्ट को इसे संभालने के लिए बस इतना स्मार्ट होना चाहिए। StreamReader क्लास की तरह यह बहुत अच्छी तरह से करता है। – ygoe

उत्तर

19

फ़ाइल UTF8 माना जाता है, तो क्यों आप इसे UTF8 डिकोडिंग पढ़ने की कोशिश नहीं करते हैं:

Get-Content -Path test.txt -Encoding UTF8 
+2

क्योंकि, आधिकारिक दस्तावेज के अनुसार, यह पैरामीटर भी मौजूद नहीं है? मैं इसके बारे में कैसे जान सकता हूं? मै उसे करने की एक कोशिश तो करूंगा। – ygoe

3

सच JPBlanc सही है। यदि आप इसे यूटीएफ 8 के रूप में पढ़ना चाहते हैं तो निर्दिष्ट करें कि जब फ़ाइल पढ़ी जाती है।

एक तरफ ध्यान दें, आप यहां [स्ट्रिंग] + [स्ट्रिंग] सामान के साथ स्वरूपण खो रहे हैं। उल्लेख नहीं है कि आपका रेगेक्स मैच काम नहीं करता है। रेगेक्स खोज परिवर्तनों को देखें, और $ 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 
+0

इससे बेहतर हुआ। रेगेक्स स्वयं अच्छा था, सिर्फ इतना नहीं कि मैंने इसका इस्तेमाल कैसे किया। मैंने पाया कि कहीं और ... क्या रेगेक्स स्ट्रिंग को डुप्लिकेट किए बिना कोई रास्ता नहीं है?इसके अलावा, अंतिम आदेश में अल्पविराम क्या करता है? मैं शुरुआत में अंत में जोड़े गए कई अतिरिक्त नई लाइनों को देखता हूं। – ygoe

+0

मिला, यह एक सरणी होना चाहिए। दुर्भाग्यवश पहले रन के लिए खाली $ डेटा अतिरिक्त लाइनों का कारण बनता है। - और दो तारों के + ऑपरेटर ने अपनी वास्तविक सामग्री क्यों बदल दी है? यह किसी भी प्रोग्रामिंग भाषा में मेरे लिए नया है। – ygoe

+0

ठीक है, यह 'गेट-कंटेंट' की गलती है। यह मुझे लाइनों की एक सरणी देता है, न कि एक मल्टीलाइन स्ट्रिंग। इससे अराजकता के सभी प्रकार होते हैं। मैंने '[System.IO.File] :: ReadAllText()' और '[System.IO.File] :: WriteAllText()' पर स्विच किया है और अब मुझे और अधिक अनुमानित परिणाम मिलते हैं। – ygoe

0

हो जाओ-सामग्री को UTF-फ़ाइलें (यदि आप एन्कोडिंग-ध्वज को छोड़ देते हैं) सब पर बीओएम बिना संभाल करने प्रतीत नहीं होता। 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!