我正在尝试编写脚本来更改我的 apache 配置文件 (httpd.conf)。我尝试匹配以下字符串:
#
# DirectoryIndex: sets the file that Apache will serve if a directory
并在前面添加以下文本:
#
# Allow server status reports generated by mod_status,
# with the URL of http://servername/server-status
# Change the ".example.com" to match your domain to enable.
#
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from localhost ip6-localhost 127.0.0.1 192.168.0.0/255.255.255.0
</Location>
我的理解是 sed 不支持多行匹配,awk 似乎很难进行多行匹配。我试图让 perl 使用 perl -0777 -pi -e,但我似乎无法找出与原始模式匹配的正则表达式。
我更愿意将其作为一行程序来完成 - 而不是脚本,因为我希望它是可移植的(即根据需要复制和粘贴)。
有没有 perl regex 专家可以帮我想出解决方案?
非常感谢 Brad
编辑
以下工作:
sed -i -e ':begin;$!N;s/#\n# DirectoryIndex/#\n# Allow server status reports generated by mod_status,\n# with the URL of http:\/\/servername\/server-status\n# Change the ".example.com" to match your domain to enable.\n#\n<Location \/server-status>\n\tSetHandler server-status\n\tOrder deny,allow\n\tDeny from all\n\tAllow from localhost ip6-localhost 192\.168\.0\.0\/255\.255\.255\.0\n<\/Location>\n\n#\n\#DirectoryIndex/;tbegin;P;D' /etc/httpd/conf/httpd.conf
但是#和DirectoryIndex之间没有空格。
但是如果我尝试将其更改为:
sed -i -e ':begin;$!N;s/#\n# DirectoryIndex/#\n# Allow server status reports generated by mod_status,\n# with the URL of http:\/\/servername\/server-status\n# Change the ".example.com" to match your domain to enable.\n#\n<Location \/server-status>\n\tSetHandler server-status\n\tOrder deny,allow\n\tDeny from all\n\tAllow from localhost ip6-localhost 192\.168\.0\.0\/255\.255\.255\.0\n<\/Location>\n\n#\n\# DirectoryIndex/;tbegin;P;D' /etc/httpd/conf/httpd.conf
sed 命令挂起并且无法完成。我似乎无法弄清楚原因?
唯一的区别是# 和 DirectoryIndex 之间的空格。
答案1
使用 awk,如何:
- 将每一行存储在“上一行”的变量中
- 如果当前行与您要查找的第二行 (DirectoryIndex) 匹配,则检查上一行的变量
- 如果它们都匹配
- 打印 bumpf
- 打印“当前行”
- 打印被吞掉的 '#'
- 别的
- 打印当前行
- 使用当前行更新“上一行”变量。
这应该对您有用,因为您并不严格需要将文本添加到前面 - 因为您要查找的文本和要插入的文本都以原始文本开头,#
您可以保留原始文本#
,在中间插入文本减去第一#
行,然后打印原始第二行,然后打印另一行#
作为您未添加的行。
您必须填写全文,但这里有足够的内容让我相信它可以起作用;)
gawk "{if (a==\"#\" && /^# DirectoryIndex/) {print \"# Allow Server\n#With the URL\n#\"; print $0} else {print $0}} {a=$0}" httpd.conf > ??
(我的双引号转义适用于 Windows 的命令提示符。请根据需要进行调整)。
编辑 bash 的引用:
gawk '{if (a=="#" && /^# DirectoryIndex/) {print "# Allow Server\n# With the URL\n#"; print $0} else {print $0}} {a=$0}' httpd.conf
答案2
你应该试试
perl -0777 -i.original -pe 's/#\n# DirectoryIndex: sets the file that Apache will serve if a directory/#\n# DirectoryIndex: sets the file that Apache will serve if a directory\n#\n# Allow server status reports generated by mod_status,\n# with the URL of http:\/\/servername\/server-status\n# Change the ".example.com" to match your domain to enable.\n#\n<Location \/server-status>\n SetHandler server-status\n Order deny,allow\n Deny from all\n Allow from localhost ip6-localhost 127.0.0.1 192.168.0.0\/255.255.255.0\n<\/Location>/igs' /etc/httpd/conf/httpd.conf
在正则表达式工具中使用 / 分隔符时,不要忘记转义字符串replace
(\/
for )/
如果你通过 shell 运行它,你可以执行如下脚本
#Set serach delimiter
search='#\n# DirectoryIndex: sets the file that Apache will serve if a directory'
#Set replace string from file
replace=$search"\n"$(cat newConfFile)
#Escape "/" char
replace=${replace//\//\\\/ }
#Launch the script
perl -0777 -i.original -pe 's/${search}/${replace}/igs' /etc/httpd/conf/httpd.conf
使用 newConfFile 包含要添加的虚拟主机配置
这是一个 Bash 函数,用于测试某个函数是否存在
#return 0 if command exist else return 1
canExec()
{
type "$1" &> /dev/null ;
}
例如canExec sed
测试你的系统上是否存在 sed 命令