在一个大文件中搜索并添加一个模式

3

我有一个大的 Apache 配置文件,在每个虚拟主机部分中,我想添加自己的日志记录。我想知道是否可以使用脚本来完成。

我的当前配置文件类似于这样:

ServerName abc.com   
some information.   
…   
……   

我希望将其呈现为以下样式:

ServerName abc.com    
CustomLog "/usr/local/logs/abc.com.log"    
some information.    
…   
……       

有没有一些脚本可以实现这个功能?我有很多这样的虚拟主机条目,手动更新是不可能的...有什么想法吗?

5个回答

5
Sed会很快地完成这个任务:
sed 's=^ServerName \(.*\)=&\nCustomLog "/usr/local/logs/\1.log"='

编辑:我之前发布了其他内容,然后测试了一下发现自己犯了一个错误。所以我测试了choroba的答案,发现那也不太行,于是我进行了修复并简化了它。


谢谢您的帮助...但是它在同一行打印而不是下一行。 - Sangfroid
请忽略我之前的评论...那是BSD出了问题..在Linux中它可以工作。非常感谢。 - Sangfroid
顺便问一下,如果我想在找到servername模式后的第3行之后才添加自定义日志,我该怎么做?如果您能推荐任何关于这些命令的好教程,我也会非常感激...我想知道如何捕鱼 :) 谢谢。 - Sangfroid
@Sangfroid,你可以使用awk来完成。我已经添加了一个解决方案,可能会帮助你解决问题。 - jaypal singh
谢谢Jaypal。稍微修改了一下就成功了...顺便问一下,你有什么建议的书籍吗? - Sangfroid
@Sangfroid 我建议你看一下这个教程和这个指南 - jaypal singh

1
尝试使用这个sed脚本:
sed -i~ '/^ServerName /s=^serverName \(.*\)=&\nCustomLog "/usr/local/logs/\1.log"=' config_file*

(未经测试)


1

awk 可以更简单易用。

awk 'NR==3{print "my log"}1' INPUT_FILE
  • NR 是一个内置变量,用于跟踪行号。
  • 您还可以使用 -v变量名 动态传递值,而不是在脚本中硬编码。例如:awk -v line="$var" 'NR==line{print "my log"}1' INPUT_FILE。在这种情况下,line 是一个 awk 变量,$var 可以是您在 awk 范围之外定义的 bash 变量。

测试:

[jaypal:~/Temp] cat file
ServerName abc.com   
some information.   
…   
……  

[jaypal:~/Temp] awk 'NR==3{print "my log"}1' file # add log after 2 lines
ServerName abc.com   
some information.   
my log
…   
……  

[jaypal:~/Temp] awk 'NR==4{print "my log"}1' file # add log after 3 lines
ServerName abc.com   
some information.   
…   
my log
……  

[jaypal:~/Temp] var=2 # define a variable which holds the line number you want to print on
[jaypal:~/Temp] awk -v line="$var" 'NR==line{print "my log"}1' file
ServerName abc.com   
my log
some information.   
…   
……  

在评论中,我看到了你关于在匹配模式(例如ServerName)后的3行中添加日志的问题。为此,你可以尝试类似这样的方法 -
awk '/ServerName/{a=NR;print;next} NR==(a+3){print$0;print "我的日志";next}1' 文件
[jaypal:~/Temp] awk '/ServerName/{a=NR;print;next} NR==(a+3){print$0;print "my log";next}1' file
ServerName abc.com   
some information.   
…   
……  
my log

0

实际上,当我在我的Mac上尝试这些答案时,它们都没有起作用,原因如下:

  • sed需要在打开和关闭括号之前加上\来进行分组
  • \n放入替换模式中只会插入一个n
  • 反向引用\1a操作中不起作用

这是一个有效的命令:

sed -i.bak 's~^ServerName \(.*\)$~&\
CustomLog "/usr/local/logs/\1.log"~g' *.conf

0

这将在正确的ServerName之后的第3行添加所需的行。

perl -i~ -ne'
   print;
   $target = $.+3 if /^\QServerName abc.com\E\s*$/;
   print qq{CustomLog "/usr/local/logs/abc.com.log"\n}
      if $target && $. == $target;
' apache.conf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接