如何用sed/awk等命令在Nginx配置首个有效location前插入内容?
解决Nginx配置中在第一个未注释location前插入自定义配置的问题
需求说明
需要在CI流程中动态修改Nginx配置,目标是仅在第一个未被注释的location块前插入指定配置段,现有sed命令会在所有匹配的location前插入内容,不符合只执行一次的要求。
原始Nginx配置
server { #location /api/graphql { # modsecurity off; # proxy_pass http://10.1.0.4; #} location 73347347 { proxy_pass 123; } location 123 { proxy_pass 123; } location / { modsecurity off; proxy_pass http://10.1.0.4; } }
可行解决方案
以下提供两种经过验证的脚本实现方式,均能满足仅插入一次的需求:
方案1:使用sed命令
修改你的test.sh脚本为如下内容:
#!/bin/bash # 构造要插入的location配置段 location=" location /projects/$1/$2 { proxy_pass http://10.1.0.6:$3; }" # 在第一个未注释的location前插入配置 sed "0,/^[[:space:]]*location/{//i $location\n\n}" nginx.conf
命令解释:
^[[:space:]]*location:匹配行首包含任意空白字符(空格/制表符)的未注释location行,排除被#注释的行0,/pattern/:限定处理范围为从文件开头到第一次匹配到pattern的行,确保只操作一次//i $location\n\n:在匹配到的行前插入预定义的location配置段,\n\n用于添加换行分隔,保证格式清晰
方案2:使用awk命令
如果更倾向awk实现,可使用如下脚本(避免shell变量解析问题):
#!/bin/bash location=" location /projects/$1/$2 { proxy_pass http://10.1.0.6:$3; }" # 传递shell变量给awk,插入配置 awk -v loc="$location" '!done && /^[[:space:]]*location/ {print loc "\n\n"; done=1} 1' nginx.conf
命令解释:
-v loc="$location":将shell中的location变量传递给awk的loc变量,避免双引号内的变量被shell提前解析!done && /^[[:space:]]*location/:判断是否为第一次遇到未注释的location行- 打印配置段后标记
done=1,后续不再执行插入操作 1:表示打印所有行,保证原配置内容完整输出
测试验证
执行命令:
./test.sh test 2.0.0 5000
得到的期望输出配置如下:
server { #location /api/graphql { # modsecurity off; # proxy_pass http://10.1.0.4; #} location /projects/test/2.0.0 { proxy_pass http://10.1.0.6:5000; } location 73347347 { proxy_pass 123; } location 123 { proxy_pass 123; } location / { modsecurity off; proxy_pass http://10.1.0.4; } }
内容的提问来源于stack exchange,提问作者Hardware noob
相关产品推荐
相关产品推荐

