Find and Replace Strings in Multiple Files

Tagged: 

This topic contains 9 replies, has 6 voices, and was last updated by Profile photo of Ataur Rasool Ataur Rasool 10 months ago.

  • Author
    Posts
  • #22862
    Profile photo of BJTys
    BJTys
    Participant

    Hello and my apologies up front if this has been addressed under a different post. Honestly, I've read so much over the past few days my head hurts,

    My Goal: Search all files in a given path (including sub-directories) and replace strings with new strings.

    For example: Search all files in c:\temp\* and d:\temp* for "servername1" and "servername2" and replace those strings with "newservername1" and "newservername2".

    I haven't convinced myself I want this all in one script as there may be files like Web.configOLD that I would not want to update. That said once I find out what file(s) contain these strings I can then make a decision how to proceed and will eventually want this all in one script.

    I can successfully gather the path and file name into a file using the following:

    $Date = Get-Date -Format MM_dd_yyyy
    $exclude = @("*log*", "*bak*")
    $SearchString = 'Server1', 'Server2', 'Server3'
    $FileName = "$Date ServerNamesSearchResults"
    Get-ChildItem -Path "D:\temp", "c:\temp" -Recurse -exclude $exclude | Select-String $SearchString | Select-Object -Unique Path | FT -hide | Out-File "D:\PSScripts\Results\$FileName.txt"

    This results in a text file that contains something like this:

    D:\temp\New Text Document.txt
    C:\temp\New Text Document (2).txt
    C:\temp\New Text Document.txt

    Now the hard part.

    I now want to replace the strings "servername1" and "servername2" in each of these files with "newservername1" and "newservername2"

    Please help. I'm sure there is even a better way to do this but I haven't figured it out.

  • #22864
    Profile photo of Ondrej Zilinec
    Ondrej Zilinec
    Participant

    Are you trying to rename files in directories? Or you want to replace string [b]inside[/b] files?

    • #22875
      Profile photo of BJTys
      BJTys
      Participant

      Replace multiple strings inside multiple files.

    • #22885
      Profile photo of Ondrej Zilinec
      Ondrej Zilinec
      Participant

      What about this:

      [b]Get-Children D:\temp *.txt -recurse | ForEach
      {
      (Get-Content $_ | ForEach {$_ -replace "old", "new"}) | Set-Content $_
      }
      [/b]

  • #22872
    Profile photo of Kiran Reddy
    Kiran Reddy
    Participant


    Get-ChildItem -Path "D:\temp", "c:\temp" -Recurse -exclude $exclude | Select-String $SearchString -List | Select-Object -Expand Path | Out-File "D:\PSScripts\Results\$FileName.txt"

    you can use regex replace

    [regex]::replace(
    string input,
    string pattern,
    System.Text.RegularExpressions.MatchEvaluator evaluator
    )

    Input will be the a "raw" string from Get-content, pattern – the string you want to match and evaluator is a scriptblock like so { "newservername1"}
    you would want to use a loop to run through each file path listed in $filename.txt and replace using the above constructor.

  • #22878
    Profile photo of BJTys
    BJTys
    Participant

    @kiran Sorry but you lost me.

  • #22889
    Profile photo of Kiran Reddy
    Kiran Reddy
    Participant

    The method proposed by Ondrej is probably easier to understand, so if it works for you go with that. But i would like to add though that you can use "-replace" more than once like so. This should take care of multiple instances of "old" strings and it is case-insensitive.


    ForEach {$_ -replace "old", "new" -replace "old1","new1"}

    also note the above code will make changes to the original file so if you want to send the changes to a new file you can do:


    Set-Content (join-path (C:\temp) -childpath ("new" + (split-path $_ -leaf) ))

  • #23438
    Profile photo of Andrew Pearce
    Andrew Pearce
    Participant

    Just another option, I'm using the Get-Content | Set-Content way to update multiple .xml files in one of my functions.

    $InputFiles = Get-Item "pathtofiles\*.xml"
    $OldString  = 'StringToReplace'
    $NewString  = 'UpdatedString'
    $InputFiles | ForEach {
        (Get-Content -Path $_.FullName).Replace($OldString,$NewString) | Set-Content -Path $_.FullName
    }
    
  • #23482
    Profile photo of H Man
    H Man
    Participant

    Try This

    
    $exclude = @("*log*", "*bak*")
    $files = Get-ChildItem -Path "D:\temp", "c:\temp" -Recurse -exclude $exclude 
    
    foreach ($file in $files){
    
    $find = "Server1"
    $replace = "NewServername1"
    $content = Get-Content $($file.FullName) -Raw
    #write replaced content back to the file
    $content -replace $find,$replace | Out-File $($file.FullName) 
    }
    
    
  • #35228
    Profile photo of Ataur Rasool
    Ataur Rasool
    Participant

    H Man,

    Is it possible to use the script in order to change dates in a word document? For example:

    100 Documents in ../bodies/ folder

    $FindMonth = "January" + "February" + "March" + "April" + "May" + "June" + "July" + "August" + "September" + "October" + "November" + "December"
    $FindDay = "1" + "2" + "3" > etc
    $ReplaceWith = "{ TIME \@ MMMM D,YYYY}"

    Could something like that be coded? Also, in some of these documents there are numbers the office uses to designate certain codes.

    Please advise.

    Thank you,
    Ray

    $content = Get-Content $($file.FullName) -Raw

You must be logged in to reply to this topic.