Regex to match nginx location block?

383 Views Asked by At

I am working on a bash script that can add nginx location blocks to a file taking in a URL. To prevent duplicates this script will also remove them if if it already exists.

For removing a block if it already exists I made the regex below. ^location\s\/${URLGOESHERE} {[\s\S]*?(?=\n{2,})$

The regex needs to match the entire multiline block like this:

location /URLGOESHERE {
  try_files $uri /URLGOESHERE/index.php?$query_string;
}

I would like the regex to match anything inside the block until the close bracket} There will be multiple blocks inside the file e.g

location /URL1HERE {
  expires 7d;
  try_files $uri /URLGOESHERE/index.php?$query_string;
  allow all;
  Etc....
}

location /URL2HERE {
  try_files $uri /URLGOESHERE/index.php?$query_string;
}
location /URL3HERE {
  try_files $uri /URLGOESHERE/index.php?$query_string;
}

location /URL4HERE {
  expires 7d;
  try_files $uri /URLGOESHERE/index.php?$query_string;
  allow all;
  Etc....
}

The regex I made works but only if there is a blank line before and after the block. So with my regex URL2, 3(No newline either before or after) and 4 (No newline at end of file) would not be found by pcregrep

I was wondering if the regex can be made to match the block exactly without needing these blank lines.

1

There are 1 best solutions below

4
RavinderSingh13 On

EDIT: Since OP has changed samples, so adding following solution now. Based on current shown samples only.

awk '/location \/URL([0-9]+)?HERE[[:space:]]+?/{found=1} found; /}/ && found{found=""}'  Input_file


With your shown samples/attempts, please try following awk code. This will give statements between { to } removing new lines from it.

awk -v RS='location[[:space:]]+/URLGOESHERE[[:space:]]+{\n*[[:space:]]+try_files[[:space:]]+\\$uri[[:space:]]+\\/[^?]*\\?\\$query_string;\n*}' '
RT{
  gsub(/.*\n*{\n*[[:space:]]+/,"",RT)
  gsub(/\n*}/,"",RT)
 print RT
}
'  Input_file

Explanation: Making field separator as per shown samples to match values to get Location block including blank lines and then in each matched separator value removing blank lines.

For example let's say we have following Input_file:

cat Input_file
location /URLGOESHERE {

  try_files $uri /URLGOESHERE/index.php?$query_string;



}

location /URLGOESHERE {
  try_files $uri /URLGOESHERE/index.php?$query_string;
}

After running above code we will get following output:

try_files $uri /URLGOESHERE/index.php?$query_string;
try_files $uri /URLGOESHERE/index.php?$query_string;

Explanation of regex used: Adding detailed explanation for above code.

location[[:space:]]+/URLGOESHERE   ##Matching location followed by spaces followed by /URLGOESHERE
[[:space:]]+{\n*                   ##Followed by spaces { and 0 or more new lines.
[[:space:]]+try_files[[:space:]]+  ##Followed by spaces try_files followed by 1 or more spaces.
\\$uri[[:space:]]+                 ##followed by $uri spaces here.
\\/[^?]*\\?\\$query_string;\n*}    ##followed by / till ? occurrence followed by $query_stirng; followed by 0 or more new lines.