skip to Main Content

I’m trying to use sed with regex to remove specific patterns from a file.
Here is the command I’m using:

sed '/location .*?/s+{(?:[wW]+?)}s*(?=(?:location|$))/d'

Here is a sample text I’m testing with:

location / {
                try_files $uri $uri/ /index.php?$args;
}
location ~*  .(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 365d;
        }

        location ~*  .(pdf)$ {
            expires 30d;
        }

        location ~ .php$
                {
                        try_files $uri =404;
                        fastcgi_split_path_info ^(.+.php)(/.+)$;
                        include /etc/nginx/fastcgi_params;
                        fastcgi_index index.php;
                        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                        include /etc/nginx/nginx_limits.conf;
                        if (-f $request_filename)
                        {
                                fastcgi_pass unix:/usr/local/php73/sockets/rgeoipdsm1.sock;
                        }
                }
        location ~ / {
                        try_files $uri $uri/ /index.php?$args;
        }

        location ^ / {
                        try_files $uri $uri/ /index.php?$args;
        }

        location ~ / {
                        if (-f $request_filename)
                        {
                                fastcgi_pass unix:/usr/local/php73/sockets/rgeoipdsm1.sock;
                        }
                        try_files $uri $uri/ /index.php?$args;
        }

location ~ .png {

}

location ~ / {
}

What I’m expecting to see after running sed:

location ~*  .(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 365d;
    }
    
    location ~*  .(pdf)$ {
        expires 30d;
    }

        location ~ .php$
                {
                        try_files $uri =404;
                        fastcgi_split_path_info ^(.+.php)(/.+)$;
                        include /etc/nginx/fastcgi_params;
                        fastcgi_index index.php;
                        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                        include /etc/nginx/nginx_limits.conf;
                        if (-f $request_filename)
                        {
                                fastcgi_pass unix:/usr/local/php73/sockets/rgeoipdsm1.sock;
                        }
                }
    location ~ .png {

}

But after running sed I get no changes at all, it seems to match nothing.
Is it possible to fine-tune this command (perhaps with escape characters?) so it’ll remove the required patterns?

2

Answers


  1. You can use

    sed '/^[[:blank:]]*location .*/[[:blank:]]*{[[:blank:]]*$/,/^[[:blank:]]*}[[:blank:]]*$/d' yourfile > newfile
    

    This sed command finds blocks of lines between line matching ^[[:blank:]]*location .*/[[:blank:]]*{[[:blank:]]*$ and a line matching ^[[:blank:]]*}[[:blank:]]*$, and removes them (with d).

    The ^[[:blank:]]*location .*/[[:blank:]]*{[[:blank:]]*$ regex matches

    • ^ – start of string
    • [[:blank:]]* – zero or more spaces/tabs
    • location – a location string
    • .* – any zero or more chars
    • / – a / char
    • [[:blank:]]*{[[:blank:]]* – a `{~ enclosed with zero or more spaces/tabs
    • $ – end of string.

    The ^[[:blank:]]*}[[:blank:]]*$ regex matches a string that only contains a single } char eclosed with optional spaces/tabs.

    Login or Signup to reply.
  2. This might work for you (GNU sed):

    sed -E '/location ([~^] )?/ {/{:a;N;/^(s*)location.*n1}s*$/d;ba}' file
    

    Match the location required, then append lines until the white space before the closing } matches the opening lines initial white space and delete those line.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search