Saturday, September 11, 2010

Recursive Text File Replacement in Powershell

Text manipulation is something that Powershell is very natural at.

For example, the script below, finds all string occurrences that matches the given regex and replace them as necessary in any file and subfolder. I can think of a great deal of use for this, especially when changing localization texts (among other things), where the Visual Studio built in  string replace is simply too inclusive and underpowered.

--------------------------------------------Powershell Script-------------------------------------------------------------

gci -r -i <#The files to search for eg. @("*.aspx","*.cs","*.resx") #>    | %{
        [bool] $SomethingChanged = $false;
        $newContent =
            (
                gc $_.FullName| %{
                            if($_ -match <#PUT YOUR REGEX HERE (in Quotes)!#>)                                                
                             {                                                
<#PUT YOUR STRING REPLACE LOGIC IN THIS BLOCK OF CODE AND SET $SomethingChanged TO TRUE IF SUCCESSFUL#>                                               
                             }
                            else  #No match found, output the original string.                          
                            {
                                $_
                            }
                        }   
            );
        if($SomethingChanged){   
            $newContent;       
            #Saves the updated content.
            sc $_.Fullname $newContent -Encoding UTF8
        }   
    }

---------------------------------------------Powershell Script-------------------------------------------------------------

The following table should help in figuring out how the script above works.

Syntax Definition
gci Get-ChildItem, it works like the “dir” in old DOS command.
-r Tells the “dir”/”gci” command to search recursively, ala. the old “/s” in normal cmd prompt.
-i This is the input filter flag. It should be followed by the filter string. eg. “*.aspx”
| Piping, it allows you to use the result from the previous computation in the next. It’s like the memory recall button in your calculator. (Note: It can be nested using parenthesis! )
$_ This variable/field stores the result piped from the previous statement. Ie. if the last computational result is “1”, then $_ == 1 is $true
% For each statement. It runs for each element, piped from the previous statement.
gc Get-Content. It’s like “type” in old DOS (which still works in powershell btw). It reads the content of a text file line by line.
sc Save-Content. Saves the content, it takes an array of string. Each element in the array, represents a line in the text file.

-

No comments:

Post a Comment