Tuesday, May 11, 2010

Powershell grep'ing

I've been asked about searching and replacing in files a few times, so I thought I'd put an example up here. This is a way to do it - and you'll almost certainly want to change it around to better suit your scenario.

cd C:\Users\michael.DOMAIN\Workspace\Powershell
function pgrep
{
 Param (
 
  [string]
  [parameter(mandatory=$true)]
  $Like,
 
  [bool]
  $Recurse = $false,
  
  [string]
  $BasePath
 )
 
 Process {
  if( -not $BasePath )
  {
   $BasePath = $PWD
  }
  
  # there's gotta be a slicker way
  $recurse_string = ""
  if( $Recurse )
  {
   $recurse_string = "-Recurse"
  }
  
  Invoke-Expression "Get-ChildItem -Path $BasePath $recurse_string" | 
  where {$_.PSIsContainer -eq $false } |
  foreach {
 
   $file = $_
   # $file.FullName
   # Get-Content -Path $file.FullName | where { $_ -eq "MachineName" }
   if( Get-Content -Path $file.FullName | where { $_ -like $Like } )
   {
    $file
   }
  } 
 }
}

function preplace
{
 Param (
  [string]
  $Path,
  
  [string]
  $From,
  
  [string]
  $To
 )
 
 Process {
  $fi = New-Object -TypeName System.IO.FileInfo -ArgumentList $Path
  $tmpfile = "$($fi.DirectoryName)\$($fi.Name).tmp"
  Remove-Item -Path $tmpfile -ErrorAction SilentlyContinue
 
  Get-Content $Path | 
   foreach {
    $line = $_
    $line.Replace( $From, $To )
   } |
   Add-Content -Path $tmpfile
  
  Remove-Item -Path $Path -ErrorAction SilentlyContinue
  Rename-Item -Path $tmpfile $Path
 }
}


pgrep -Like "*MachineName*" -BasePath C:\Users\michael.DOMAIN\Workspace\Powershell |

foreach {
 $fi = $_
 Write-Host "updating $($fi.FullName)"
 preplace -Path $fi.FullName -From "MachineName" -To "MachineFoo"
}

1 comment: