Reputation: 51
I'm just trying to add a linebreak before UNION, I've tried both of the following commands. The all modify the file (Date gets updated) But it doesn't add the new line.
(Get-Content \\C\ELL.sql) -replace "UNION select hash(0)","`r`nUNION select hash(0)" | Set-Content \\C\ELL.sql
(Get-Content \\C\ELL.sql) -replace 'UNION select hash(0)','`r`nUNION select hash(0)' | Set-Content \\C\ELL.sql
My replaces worked in the past, when no line break was involved.
Anyone knows what's causing the issue? Thank you
Upvotes: 2
Views: 53
Reputation: 440586
Your problem isn't with newlines, it is due to the fact that the replace
operator is regex-based.
Therefore, your search pattern, "UNION select hash(0)"
effectively only matches UNION select hash0
(note the absence of (
and )
), which therefore doesn't match the intended lines, so no replacement occurs at all.
The reason is that (...)
in a regex is a capture group - (
and )
are not treated literally - you have to escape them, namely as \(
and \)
:
(Get-Content \\C\ELL.sql) -replace "UNION select hash\(0\)", "`r`n`$&" |
Set-Content \\C\ELL.sql
Note the use of $&
(escaped as `$&
to prevent PowerShell from interpreting it) in the substitution operand, which refers to what the regex captured (matched), obviating the need to repeat the text. You're free to use literal text in the replacement, but note that any literal $
characters must be escaped as $$
(or, inside a "..."
string, as `$`$
); see this answer for a summary of what $
-prefixed placeholders are supported.
You can alternatively perform the escaping programmatically, on your entire string, using [regex]::Escape()
:
(Get-Content \\C\ELL.sql) -replace ([regex]::Escape("UNION select hash(0)"), "`r`n`$&" |
Set-Content \\C\ELL.sql
That said, as Santigo Squarzon points out, you could use the [string]
type's .Replace()
.NET method, which (only) performs literal replacements, but there are two caveats:
Unlike -replace
, .Replace()
is case-sensitive, invariably in Windows PowerShell and by default in PowerShell (Core) 7+.
You don't get the convenience of referring to (parts of) what was matched in the replacement string (such as $&
used with -replace
), which is also a literal.
See the bottom section of this answer for general guidance on when to use -replace
vs. .Replace()
Upvotes: 2