使用 perl/awk/sed 添加字符串?

使用 perl/awk/sed 添加字符串?

我正在尝试编写脚本来更改我的 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 命令

相关内容