20

I want to replace some text in every script file in folder, and I'm trying to use this PS code:

$pattern = '(FROM [a-zA-Z0-9_.]{1,100})(?<replacement_place>[a-zA-Z0-9_.]{1,7})'
Get-ChildItem -Path 'D:\Scripts' -Recurse -Include *.sql | ForEach-Object { (Get-Content $_.fullname) -replace $pattern, 'replace text' | Set-Content $_.fullname }

But I have no idea how to keep first part of expression, and just replace the second one. Any idea how can I do this? Thanks.

hmnzr
  • 1,390
  • 1
  • 15
  • 24

1 Answers1

41

Not sure that provided regex for tables names is correct, but anyway you could replace with captures using variables $1, $2 and so on, and following syntax: 'Doe, John' -ireplace '(\w+), (\w+)', '$2 $1'

Note that the replacement pattern either needs to be in single quotes ('') or have the $ signs of the replacement group specifiers escaped ("`$2 `$1").

# may better replace with     $pattern = '(FROM) (?<replacement_place>[a-zA-Z0-9_.]{1,7})'
$pattern = '(FROM [a-zA-Z0-9_.]{1,100})(?<replacement_place>[a-zA-Z0-9_.]{1,7})'

Get-ChildItem -Path 'D:\Scripts' -Recurse -Include *.sql | % `
{
   (Get-Content $_.fullname) | % `
     { $_-replace $pattern, '$1 replace text' } | 
     Set-Content $_.fullname -Force
}

If you need to reference other variables in your replacement expression (as you may), you can use a double-quoted string and escape the capture dollars with a backtick

     { $_-replace $pattern, "`$1 replacement text with $somePoshVariable" } | 
syneticon-dj
  • 417
  • 5
  • 21
Akim
  • 8,469
  • 2
  • 31
  • 49
  • Thank you, thats exactly what I need. Regex correctness doesnt matter in that case, I just need to learn a way. – hmnzr Aug 03 '12 at 12:54
  • 1
    Thanks, this has been helpful in the past. I am having trouble now referencing another variable where there is no space between the first capture and the variable, like this: `Foreach-Object {$_ -replace $pattern, "\`$1$version\`$3"}`. I am wanting output of `1.1.35` but am getting `$11.1.35`, obviously the parser is not recognising I want a capture there. Is there a way around this? If I put a space between the capture and the variable it works, but then I have an extra space which breaks later. – Peter May 15 '17 at 08:42
  • @Peter did you ever find a fix for this? Having the exact same problem – user3700562 Jan 24 '18 at 13:18
  • @user3700562 - looks like I did a bit of a work-around like this: `Foreach-Object {$_ -replace $pattern, "\`$1\`>$version\`$3"}` - can't remember the details! – Peter Jan 25 '18 at 15:02
  • 11
    @user3700562 surround the # in curly braces like `${1}$version` in your case – Matti Price Feb 07 '18 at 20:53
  • It appears curly braces are the correct syntax for named capture groups as well. https://learn.microsoft.com/en-us/dotnet/standard/base-types/substitutions-in-regular-expressions#Named – dragon788 Jun 27 '19 at 17:57