用perl / awk / sed预加string?

我正在尝试将脚本更改到我的apacheconfiguration文件(httpd.conf)。 我试图匹配下面的string:

# # 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一起工作,但是我似乎无法找出与原始模式匹配的正则expression式

我宁愿把它作为一个class轮,而不是一个脚本,因为我希望它是可移植的(即根据需要复制和粘贴)。

任何Perl正则expression式的专家,可以帮助我devise一个解决scheme?

非常感谢布拉德

编辑

以下工作:

  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之间的空格。

用awk,怎么样:

  • 将每行存储在“上一行”的variables中
  • 如果当前行与您正在查找的第二行(DirectoryIndex)匹配,请使用上一行检查该variables
  • 如果他们都匹配
    • 打印bumpf
    • 打印“当前行”
    • 打印吞下的“#”
  • 其他
    • 打印当前行
  • 用当前行更新'上一行'variables。

这应该适合你,因为你不需要预先准备好文本 – 因为你正在寻找的文本和你插入的文本都以#开头#你可以保留原来的# ,插入你的文本减去第一个#中间行,然后打印原来的第二行,然后打印另一个#是你没有预先的。

你必须填写全文,但这里有足够的说服我可以工作;)

 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 

你应该试试

 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 

当你在正则expression式工具中使用/分隔符的时候,不要忘记跳过你的stringreplace\/ 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包含要添加的虚拟主机configuration

这是一个Bash函数来testing函数是否存在

 #return 0 if command exist else return 1 canExec() { type "$1" &> /dev/null ; } 

例如,如果系统上存在sed命令, canExec sed test