2010-05-14 12 views
90

मैं कई विन्यास फाइल है विशेष एक्सटेंशन वाले सभी फ़ाइलें के लिए बदलें के लिए इस तरह की तरह नेस्ट:PowerShell स्क्रिप्ट का पता लगाएं और विंडोज सर्वर 2008 पर

C:\Projects\Project_1\project1.config 

C:\Projects\Project_2\project2.config 

मेरी विन्यास में मैं एक स्ट्रिंग इस तरह की तरह की जगह करने की जरूरत है:

<add key="Environment" value="Dev"/> 

हो जाएगा:

<add key="Environment" value="Demo"/> 

मैं बैच पटकथा का उपयोग कर के बारे में सोचा है, लेकिन वहाँ ऐसा करने का कोई अच्छा तरीका नहीं था, और मैंने सुना है कि PowerShell स्क्रिप्टिंग के साथ आप आसानी से इसे निष्पादित कर सकते हैं। मुझे ढूंढने/प्रतिस्थापित करने के उदाहरण मिल गए हैं, लेकिन मैं ऐसे तरीके की उम्मीद कर रहा था जो मेरे सी: \ प्रोजेक्ट्स निर्देशिका में सभी फ़ोल्डरों को पार करेगा और '.config' एक्सटेंशन के साथ समाप्त होने वाली किसी भी फाइल को ढूंढें। जब यह एक पाता है, तो मैं इसे अपने स्ट्रिंग मानों को प्रतिस्थापित करना चाहता हूं।

यह कोई अच्छा संसाधन है कि यह कैसे करें या कोई पावरशेल गुरु जो कुछ अंतर्दृष्टि प्रदान कर सकता है?

+1

हमें बताएं कि आपको कैसे पता चला है या अगर उन फ़ाइलों के साथ कुछ अजीब स्वरूपण समस्याएं हैं जिन्हें संबोधित करने की आवश्यकता है। समस्या के बारे में एक अच्छी बात यह है कि यह उत्पादन कोड –

उत्तर

135

यहां मेरे सिर के शीर्ष पर पहला प्रयास है।

$configFiles = Get-ChildItem . *.config -rec 
foreach ($file in $configFiles) 
{ 
    (Get-Content $file.PSPath) | 
    Foreach-Object { $_ -replace "Dev", "Demo" } | 
    Set-Content $file.PSPath 
} 
+3

को प्रभावित किए बिना परीक्षण है, मैं उन सभी समाधानों का परीक्षण करना चाहता हूं जो सभी काम करते हैं, लेकिन यह पठनीयता के लिए सबसे आसान था। मैं इसे एक सहकर्मी को सौंपने में सक्षम था और वह आसानी से समझ सकता था कि क्या हो रहा था। सहायता के लिए धन्यवाद। – Brandon

+0

ग्रेट स्टफ ब्रैंडन। मैंने पूरी तरह से पावरहेल को गले लगा लिया नहीं है, लेकिन जब आप विचार करते हैं कि यह वीबीस्क्रिप्ट में कितना समय लगेगा !!!! –

+9

उपनिर्देशिका में फ़ाइलों में काम करने के लिए, आपको ".PSPath" की आवश्यकता है। दिलचस्प बात यह है कि, जब मैंने इस काम को बिना किसी सामग्री के (-) प्राप्त करने की कोशिश की, तो यह लेखन-सामग्री पर विफल रहा क्योंकि फ़ाइल लॉक हो गई थी। –

22

पावरशेल एक अच्छी पसंद है;) दी गई निर्देशिका में फ़ाइलों को गिनना बहुत आसान है, उन्हें पढ़ें और प्रक्रिया करें।

स्क्रिप्ट ऐसा दिखाई दे सकता:

Get-ChildItem C:\Projects *.config -recurse | 
    Foreach-Object { 
     $c = ($_ | Get-Content) 
     $c = $c -replace '<add key="Environment" value="Dev"/>','<add key="Environment" value="Demo"/>' 
     [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n")) 
    } 

मैं तुम्हारे लिए पठनीय होने के लिए अधिक लाइनों के लिए कोड अलग हो गए। ध्यान दें कि आप [IO.File]::WriteAllText के बजाय सेट-सामग्री का उपयोग कर सकते हैं, लेकिन यह अंत में नई लाइन जोड़ता है। WriteAllText के साथ आप इससे बच सकते हैं।

अन्यथा कोड इस तरह दिख सकता है: $c | Set-Content $_.FullName

5

मैं एक्सएमएल और xpath के साथ जाना होगा:

11

यह दृष्टिकोण अच्छी तरह से काम करता है:

gci C:\Projects *.config -recurse | ForEach { 
    (Get-Content $_ | ForEach {$_ -replace "old", "new"}) | Set-Content $_ 
} 
  • बदलें "पुराने" उनके संबंधित मान को 'नई' (या चर का उपयोग करें)।
  • ब्रांड्स को न भूलें - जिसके बिना आपको एक एक्सेस त्रुटि प्राप्त होगी।
4

इस powershell उदाहरण स्ट्रिंग के सभी उदाहरणों के लिए लग रहा है "\ foo \" एक फ़ोल्डर और इसके उप-में, "\ foo \" "\ बार \" के साथ बदल देता है और फ़ाइलों को शामिल नहीं है फिर से लिखना नहीं करता स्ट्रिंग "\ foo \" इस तरह आप फ़ाइल अंतिम अद्यतन दिनांक टिकटों जहां स्ट्रिंग नहीं मिला था नष्ट नहीं है:

Get-ChildItem -Path C:\YOUR_ROOT_PATH\*.* -recurse 
| ForEach {If (Get-Content $_.FullName | Select-String -Pattern '\\foo\\') 
      {(Get-Content $_ | ForEach {$_ -replace '\\foo\\', '\bar\'}) | Set-Content $_ } 
      } 
3

मैं एक फ़ाइल में पाठ बदलने के लिए एक छोटे से सहायक समारोह में लिखा है:

function Replace-TextInFile 
{ 
    Param(
     [string]$FilePath, 
     [string]$Pattern, 
     [string]$Replacement 
    ) 

    [System.IO.File]::WriteAllText(
     $FilePath, 
     ([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement) 
    ) 
} 

उदाहरण:

Get-ChildItem . *.config -rec | ForEach-Object { 
    Replace-TextInFile -FilePath $_ -Pattern 'old' -Replacement 'new' 
} 
1

मुझे @Artyom उपयोगी टिप्पणी मिली लेकिन दुर्भाग्य से उन्होंने एक उत्तर पोस्ट नहीं किया है।

स्वीकार्य उत्तर की मेरी राय में सबसे अच्छा संस्करण यह छोटा संस्करण है;

ls *.config -rec | %{$f=$_; (gc $f.PSPath) | %{$_ -replace "Dev", "Demo"} | sc $f.PSPath} 
+0

इसे समझने के लिए कुछ समय लगा, यदि कोई और इस पर चलता है, जैसा कि मैंने किया - बैच फ़ाइल से सीधे इसे निष्पादित करना चाहते हैं - यह '% 'उपनाम के बजाय' foreach-object 'का उपयोग करने में मदद कर सकता है इस तरह के एक आदेश निष्पादित। अन्यथा, इसके परिणामस्वरूप त्रुटि हो सकती है: 'अभिव्यक्तियों को केवल पाइपलाइन के पहले तत्व के रूप में अनुमति दी जाती है' –

0

जब पुनरावर्ती प्रतिस्थापन कर रही है, पथ और फ़ाइल नाम शामिल किया जाना चाहिए:

Get-ChildItem -Recurse | ForEach { (Get-Content $_.PSPath | 
ForEach {$ -creplace "old", "new"}) | Set-Content $_.PSPath } 

इस के साथ सभी "पुराने" की जगह wil 'नई' के अपने डर के सभी फाइलों में केस-संवेदी आपकी वर्तमान निर्देशिका।

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