正则表达式匹配 nginx 位置块?

问题描述

我正在编写一个 bash 脚本,该脚本可以将 Nginx 位置块添加到接收 URL 的文件中。为防止重复,如果脚本已经存在,此脚本也会将其删除

为了删除一个块,如果它已经存在,我做了下面的正则表达式。 ^location\s\/${URLGOESHERE} {[\s\S]*?(?=\n{2,})$

正则表达式需要像这样匹配整个多行块:

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

我希望正则表达式匹配块内的任何内容,直到右括号} 文件内将有多个块 例如

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....
}

我制作的正则表达式有效,但前提是块前后有空行。因此,对于我的正则表达式 URL2,pcregrep 将找不到 3(前后无换行符)和 4(文件末尾无换行符)

我想知道是否可以使正则表达式在不需要这些空行的情况下完全匹配块。

解决方法

编辑: 由于 OP 已更改示例,因此现在添加以下解决方案。仅基于当前显示的样本。

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


根据您显示的示例/尝试,请尝试遵循 awk 代码。这将给出 { 到 } 之间的语句,从中删除新行。

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

说明: 根据显示的样本制作字段分隔符以匹配值以获取包含空行的位置块,然后在每个匹配的分隔符值中删除空行。

例如,假设我们有以下 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;
}

运行上述代码后,我们将得到以下输出

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

使用的正则表达式说明: 对以上代码添加详细说明。

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.