如何用Shell脚本在Nginx.conf匹配行前十行插入指定配置?
问题分析与修复方案
你的脚本失效核心原因是sed无法直接处理包含换行的变量内容,直接用$USAGE传递给sed时,换行会被解析成空格,导致配置块被挤成一行,无法正确插入多行配置。另外如果目标文本出现多次,grep会返回多个行号,脚本也会出错。
以下是修复后的脚本:
#!/bin/bash file_path="/etc/nginx/nginx.conf" search_word="Settings for a TLS enabled server" # 用awk一次性完成查找行号、计算插入位置并插入配置块 awk -v search="$search_word" -v insert_block=' location /nginx-status { stub_status on; allow all; }' ' BEGIN { insert_line = 0 } $0 ~ search { insert_line = NR - 10 } NR == insert_line { print insert_block } 1 ' "$file_path" > temp.conf && mv temp.conf "$file_path"
修复说明:
- 使用
awk替代grep+sed的组合,避免行号处理的割裂问题,同时原生支持多行内容插入。 - 直接在awk中定义要插入的配置块,保证换行和缩进完全保留。
- 找到目标行后计算插入行号,当处理到该行时先打印配置块,再打印原行内容。
- 通过临时文件替换原文件(避免
sed -i在不同系统的兼容性问题)。
另一种sed兼容方案(适合坚持用sed的场景):
如果一定要用sed,需要将多行内容转义成sed能识别的格式:
#!/bin/bash file_path="/etc/nginx/nginx.conf" search_word="Settings for a TLS enabled server" # 只取第一个匹配的行号 line_number=$(grep -n "$search_word" "$file_path" | cut -d: -f1 | head -n1) insert_line=$((line_number - 10)) # 将配置块转义为sed可识别的多行插入格式 insert_block=$(printf ' location /nginx-status {\n stub_status on;\n allow all;\n }') # 用sed的多行插入语法 sed -i "${insert_line}i\\ ${insert_block}" "$file_path"
这个方案通过格式化配置块的换行符,确保sed能正确解析并插入多行内容。
内容的提问来源于stack exchange,提问作者anandarc
相关产品推荐
相关产品推荐

