I need to replace
location ~* "^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:32583;
by
location ~* "^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:$proxy;
I’m trying to achieve this with the following code with no success
Get-ChildItem 'C:nginxconfnginx.conf' | ForEach {
(Get-Content $_) | ForEach {$_ -Replace "location ~* ""^/(888888-localhost\/client)(.*)$"" {
proxy_pass https://localhost:.+;", "location ~* ""^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:$proxy;""} | Set-Content $_
}
How can i do this using Powershell?
2
Answers
Since you want to match across lines, you cannot use the line-by-line processing that
Get-Content
does by default. Use the-Raw
switch to read the entire file at once, into a single, multi-line string.Since both your search string and the replacement string passed to the regex-based
-replace
operator contain metacharacters, you must escape them.Note: If all you need is literal (verbatim) substring matching, including not needing to assert where the substring must match (start of the string, word boundary, …), using
[string]::Replace()
is the simpler option, however:[string]::Replace()
is invariably, case-sensitive, in PowerShell (Core) 7+ it is by default, unlike PowerShell’s operators – see this answer for guidance on when to use-replace
vs.[string]::Replace()
The search string must be escaped with
[regex]::Escape()
, so that the .NET regex engine, which the-replace
operator invariably uses, treats it as a literal.The substitution string must have any embedded
$
characters escaped as$$
, so that$
isn’t mistaken for the start of a capture-group reference.For a comprehensive overview of how
-replace
works, see this answer.Note the use of both verbatim and expandable here-strings to facilitate declaring the strings.
As for a potential simplification of your
-replace
operation:Abraham Zinala points out that ultimately you’re looking to only replace the port number in the matched substring, so you could use a positive look-behind assertion (
(?<=...)
), as shown in this simplified example:a https://localhost:8080; z
Caveat re newlines:
The above assumes that your script file uses the same newline format (Windows-format CRLF vs. Unix-format LF) as the input file.
If you’re not sure, and you want to match either format, replace the
n
escape sequence in$reSearch
withr?n
($reSearch = $reSearch.Replace('n', 'r?n')
and possibly replace the literal newline in$substitution
with`r`n
or`n
, as needed.One solution would be to use a positive lookbehind to ensure the pattern is matched:
Removing the single quotes around
$port
, or replacing them with double quotes will allow the use of$port
as an actual variable.