Sunday, January 28, 2024

[SOLVED] How to find string and replace some string between { ... }?

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 after test/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)