Issue
You only need to change the port in the /test/v2.0.0 block:
server {
location /test/v2.0.3 {
modsecurity on;
proxy_pass http://10.1.0.6:3000;
}
location /test/v2.0.0 {
modsecurity on;
proxy_pass http://10.1.0.6:3000;
}
}
sed '0,/:[0-9].*;/{s/:[0-9].*;/:5555;/}' test.nginx
- changes the first match
sed '/.*location.*\/test\/v2.0.0\/.*:[0-9].*;/{s/:[0-9].*;/:5555;/}' test.nginx
- doesn't change anything
sed 's/.*location.*\/test\/v2.0.0\/.*:[0-9].*;/:5555;/' test.nginx
- doesn't change anything
P.S.:
What the task sounds like:
Find location /test/v2.0.0.0
preceded by any character except #
, select everything in the brackets {
}
, find the port string :3000
; between them, replace it with the specified one.
Output:
server {
location /test/v2.0.3 {
modsecurity on;
proxy_pass http://10.1.0.6:3000;
}
location /test/v2.0.0 {
modsecurity on;
proxy_pass http://10.1.0.6:5555;
}
}
Solution
Why should this not be done using sed?
In the simplest calling of sed, it has one line of text in the pattern space, ie. 1 line of \n delimited text from the input
see: https://unix.stackexchange.com/a/26290/407145
Doing it using awk is not very hard:
awk '/test\/v2.0.0/{ found=1; }found==1 && /:[0-9]{4}/{ gsub(/:[0-9]{4}/,":5555"); found=0 }1' test.nginx
- When a line with
test/v2.0.0
is found (the/
needs to be escaped), the variable found is set to 1 - When found is equal to 1 and a
:
is found followed by four numbers, it is replaced by:5555
- After the change
found
should be reset. NOTE: Only the first occurrence aftertest/v2.0.0
is changed now... - The
1
at the end makes the (changed) line being outputted.
Answered By - Luuk Answer Checked By - Timothy Miller (WPSolving Admin)