मैं PowerShell वाली फ़ाइल में स्ट्रिंग की हर घटना को कैसे प्रतिस्थापित कर सकता हूं?





(10)


(Get-Content file.txt) | 
Foreach-Object {$_ -replace '\[MYID\]','MyValue'}  | 
Out-File file.txt

नोट करें कि चारों ओर कोष्ठक (Get-Content file.txt) आवश्यक है:

कोष्ठक के बिना सामग्री को पढ़ा जाता है, एक समय में एक पंक्ति, और जब तक यह फ़ाइल-फ़ाइल या सेट-सामग्री तक पहुंच जाती है, तब तक पाइपलाइन को बहती है, जो एक ही फाइल को लिखने की कोशिश करती है, लेकिन यह पहले से ही सामग्री प्राप्त करके खुली है और आपको मिलती है एक त्रुटि। कोष्ठक सामग्री को पढ़ने के एक बार (ओपन, रीड और क्लोज़) को पढ़ने का कारण बनता है। केवल तब जब सभी लाइनें पढ़ी गई हैं, वे एक समय में एक पाइप कर रहे हैं और जब वे पाइपलाइन में अंतिम कमांड तक पहुंचते हैं तो उन्हें फ़ाइल में लिखा जा सकता है। यह $ सामग्री = सामग्री के समान है; $ सामग्री | कहा पे ...

PowerShell का उपयोग करके, मैं MyValue साथ किसी दिए गए फ़ाइल में [MYID] की सभी सटीक घटनाओं को प्रतिस्थापित करना चाहता MyValue । ऐसा करने का सबसे आसान तरीका क्या है?




थोड़ा पुराना और अलग, क्योंकि मुझे किसी विशेष फ़ाइल नाम के सभी उदाहरणों में एक निश्चित पंक्ति को बदलने की आवश्यकता थी।

साथ ही, Set-Content लगातार परिणाम नहीं दे रहा था, इसलिए मुझे Out-File का सहारा लेना पड़ा।

नीचे कोड:

$FileName =''
$OldLine = ''
$NewLine = ''
$Drives = Get-PSDrive -PSProvider FileSystem
foreach ($Drive in $Drives) {
    Push-Location $Drive.Root
        Get-ChildItem -Filter "$FileName" -Recurse | ForEach { 
            (Get-Content $_.FullName).Replace($OldLine, $NewLine) | Out-File $_.FullName
        }
    Pop-Location
}

इस PowerShell संस्करण पर मेरे लिए सबसे अच्छा काम किया है:

Major.Minor.Build.Revision

5.1.16299.98




उपर्युक्त केवल एक "केवल एक फ़ाइल" के लिए चलता है, लेकिन आप इसे अपने फ़ोल्डर में एकाधिक फ़ाइलों के लिए भी चला सकते हैं:

Get-ChildItem 'C:yourfile*.xml' -Recurse | ForEach {
     (Get-Content $_ | ForEach  { $_ -replace '[MYID]', 'MyValue' }) |
     Set-Content $_
}



उपयोग करें (वी 3 संस्करण):

(Get-Content c:\temp\test.txt).replace('[MYID]', 'MyValue') | Set-Content c:\temp\test.txt

या वी 2 के लिए:

(Get-Content c:\temp\test.txt) -replace '\[MYID\]', 'MyValue' | Set-Content c:\temp\test.txt



आप इस तरह कुछ कोशिश कर सकते हैं:

$path = "C:\testFile.txt"
$word = "searchword"
$replacement = "ReplacementText"
$text = get-content $path 
$newText = $text -replace $word,$replacement
$newText > $path



सेट-कंटेंट कमांड के लिए छोटा सुधार। यदि खोजी गई स्ट्रिंग नहीं मिली है तो Set-Content कमांड लक्ष्य फ़ाइल खाली (खाली) होगा।

आप पहले यह सत्यापित कर सकते हैं कि आप जिस स्ट्रिंग को खोज रहे हैं या नहीं। यदि नहीं, तो यह कुछ भी नहीं बदलेगा।

If (select-string -path "c:\Windows\System32\drivers\etc\hosts" -pattern "String to look for") `
    {(Get-Content c:\Windows\System32\drivers\etc\hosts).replace('String to look for', 'String to replace with') | Set-Content c:\Windows\System32\drivers\etc\hosts}
    Else{"Nothing happened"}



यह PowerShell में वर्तमान कार्य निर्देशिका का उपयोग कर मेरे लिए काम किया। आपको FullName प्रॉपर्टी का उपयोग करने की आवश्यकता है, या यह PowerShell संस्करण 5 में काम नहीं करेगा। मुझे अपने सभी CSPROJ फाइलों में लक्ष्य .NET फ्रेमवर्क संस्करण बदलने की आवश्यकता है।

gci -Recurse -Filter *.csproj |
% { (get-content "$($_.FullName)")
.Replace('<TargetFramework>net47</TargetFramework>', '<TargetFramework>net462</TargetFramework>') |
 Set-Content "$($_.FullName)"}



मैं निम्नलिखित उदाहरण में देखे गए .NET की फ़ाइल-श्रेणी और इसकी स्थिर विधियों का उपयोग करना पसंद करता हूं।

$content = [System.IO.File]::ReadAllText("c:\bla.txt").Replace("[MYID]","MyValue")
[System.IO.File]::WriteAllText("c:\bla.txt", $content)

Get-Content साथ स्ट्रिंग-एरे के बजाए एक स्ट्रिंग के साथ काम करने का इसका लाभ है। विधियों को अधिकांश समय पर ध्यान देने के बिना फ़ाइल के एन्कोडिंग (यूटीएफ -8 BOM , इत्यादि) का भी ख्याल रखना पड़ता है।

इसके अलावा विधियां Set-Content माध्यम से गेट-कंटेंट और पाइपिंग का उपयोग करके एल्गोरिदम के विपरीत लाइन एंडिंग्स (यूनिक्स लाइन एंडिंग्स का उपयोग किया जा सकता है) को गड़बड़ नहीं करती है।

तो मेरे लिए: कम चीजें जो वर्षों से तोड़ सकती हैं।

.NET कक्षाओं का उपयोग करते समय एक छोटी सी बात यह है कि जब आपने PowerShell विंडो में "[System.IO.File] ::" टाइप किया है तो आप वहां विधियों के माध्यम से चरणबद्ध करने के लिए टैब कुंजी दबा सकते हैं।




बहुत अधिक खोज करने के बाद मैं एन्कोडिंग को बदलने के बिना ऐसा करने के लिए सबसे सरल रेखा को समझता हूं:

Get-Content path/to/file.ext | out-file -encoding ASCII targetFile.ext



आप इस तरह हैश चिह्न का उपयोग करते हैं

# This is a comment in Powershell

विकिपीडिया के पास कई लोकप्रिय भाषाओं में टिप्पणियां कैसे करें, इसका ट्रैक रखने के लिए एक अच्छा पृष्ठ है

http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(syntax)#Comments







powershell