使用 GNU sed

使用 GNU sed

我想添加以下几行

if ($http_user_agent ~* "somewebsite" ) {
    return 444;
} 

我在 NGINX 中的所有虚拟主机如下

server {
  location / {
    want_to_add_those_3_lines_here
  }
}

有任何想法吗?

答案1

使用 GNU sed

这个任务可以用 sed 来完成。

但是,如果您受限于 sed 的 POSIX 标准,那么处理这个问题就不那么容易了,因为您必须将几行与相应的模式进行比较来决定是否必须进行插入。

sed 的 GNU 实现提供了一些扩展来简化此类多行问题。

但在这种情况下最有用的工具是-zGNU sed 提供的选项,我们在下面充分利用了它。

您可以通过运行来判断您的 sed 版本是否是 GNU 实现

sed --version

将多行问题转化为单行问题

通过-zGNU sed 提供的选项,您可以选择 sed 认为的行。

通常的观点是,文件在每个换行符之后被分成几行。相反,使用该-z选项,sed 会认为行以 NULL 字节结尾。

sed -z您的每个文件中很可能只会看到一行长行。幸运的是,GNU sed 对其能够处理的行长度没有施加任何限制。

解决方案

我们选择sed-script以下脚本的名称:

#!/bin/bash

pattern="\
\(\
server {\n\
  location / {\n\
\)\(\
  }\n\
}\)\
"

replacement="\
    if (\$http_user_agent ~* \"somewebsite\" ) {\n\
        return 444;\n\
    }\n\
"

sed -z -e 's!'"$pattern"'!\1'"$replacement"'\2!g' "$1" > "$2"

如果您使该脚本可执行并像这样调用它:

./sed-script INFILE OUTFILE

它将处理INFILE寻找每次出现的

server {
  location / {
  }
}

将其替换为

server {
  location / {
    if ($http_user_agent ~* "somewebsite" ) {
        return 444;
    }
  }
}

并将结果放入OUTFILE.

我们在这里使用脚本的唯一原因是为了保持 sed 命令的结构清晰。

由于搜索模式包含斜杠 ( /),因此使用感叹号 ( !) 来分隔 sed 命令的字段。

答案2

这是使用 sed 的最新答案:

$ sed '/location/ r addy' nginx 
server {
  location / {
if ($http_user_agent ~* "somewebsite" ) {
    return 444;
} 
  }
}

在哪里:

$ cat addy 
if ($http_user_agent ~* "somewebsite" ) {
    return 444;
} 

$ cat nginx 
server {
  location / {
  }
}

相关内容