PowerShell Script for search and replace for all files with a specific extension

I have several configuration files on Windows Server 2008 attached as follows:

C:\Projects\Project_1\project1.config C:\Projects\Project_2\project2.config 

In my configuration, I need to perform a line replacement as follows:

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

will become:

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

I was thinking about using a batch script, but there was no good way to do this, and I heard that with PowerShell scripts you can easily do this. I found find / replace examples, but I was hoping for a way to traverse all the folders in my C: \ Projects directory and find any files that end with the .config extension. When he finds one, I want him to replace my string values.

Any good resources to learn how to do this, or any PowerShell gurus that might offer some insight?

+84
scripting replace find powershell
May 14 '10 at 9:36 p.m.
source share
8 answers

Here is the first attempt on my head.

 $configFiles = Get-ChildItem . *.config -rec foreach ($file in $configFiles) { (Get-Content $file.PSPath) | Foreach-Object { $_ -replace "Dev", "Demo" } | Set-Content $file.PSPath } 
+131
May 14, '10 at 21:57
source share

PowerShell is a good choice;) It is very simple to list the files in this directory, read them and process them.

The script might look like this:

 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")) } 

I split the code into more lines so that they could be read. Note that you can use Set-Content instead of [IO.File]::WriteAllText , but it adds a new line to the end. With WriteAllText you can avoid this.

Otherwise, the code may look like this: $c | Set-Content $_.FullName $c | Set-Content $_.FullName .

+22
May 14 '10 at 21:57
source share

This approach works well:

 gci C:\Projects *.config -recurse | ForEach { (Get-Content $_ | ForEach {$_ -replace "old", "new"}) | Set-Content $_ } 
  • Change the "old" and "new" to the appropriate values ​​(or use variables).
  • Do not forget the brackets - without which you will receive an access error.
+10
01 Oct '13 at 2:24
source share

I would go with xml and xpath:

 dir C:\Projects\project_*\project*.config -recurse | foreach-object{ $wc = [xml](Get-Content $_.fullname) $wc.SelectNodes("//add[@key='Environment'][@value='Dev']") | Foreach-Object {$_.value = 'Demo'} $wc.Save($_.fullname) } 
+4
May 15, '10 at 23:34
source share

This powershell example looks for all instances of the string "\ foo \" in the folder and its subfolders, replaces "\ foo \" with "\ bar \" AND DOES NOT OPEN files that do not contain the string "\ foo \" Thus, you do not destroy latest datetime data of recent updates where the row was not found:

 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 $_ } } 
+4
May 22, '15 at 21:15
source share

I wrote a small helper function to replace text in a file:

 function Replace-TextInFile { Param( [string]$FilePath, [string]$Pattern, [string]$Replacement ) [System.IO.File]::WriteAllText( $FilePath, ([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement) ) } 

Example:

 Get-ChildItem . *.config -rec | ForEach-Object { Replace-TextInFile -FilePath $_ -Pattern 'old' -Replacement 'new' } 
+2
May 26 '16 at 18:29
source share

I found the @Artyom comment useful, but unfortunately it did not send a response.

This is a short version, in my opinion, of the best version of the accepted answer;

 ls *.config -rec | %{$f=$_; (gc $f.PSPath) | %{$_ -replace "Dev", "Demo"} | sc $f.PSPath} 
0
May 9 '17 at 16:46
source share

When performing a recursive replacement, you must specify the path and file name:

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

This wil will replace all "old" with "new" case-sensitive in all files of your folders in your current directory.

0
Jul 25 '17 at 11:25
source share



All Articles