Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在大文件中搜索并添加图案_Linux_Perl_Shell_Unix_Awk - Fatal编程技术网

Linux 在大文件中搜索并添加图案

Linux 在大文件中搜索并添加图案,linux,perl,shell,unix,awk,Linux,Perl,Shell,Unix,Awk,我有一个很大的apache配置文件,在每个virtualhost部分中,我想添加自己的日志条目。我想知道我是否可以用脚本来完成它 我当前的配置文件是这样的 ServerName abc.com some information. … …… 我想拥有这样的东西 ServerName abc.com CustomLog "/usr/local/logs/abc.com.log" some information. … …… 通过

我有一个很大的apache配置文件,在每个virtualhost部分中,我想添加自己的日志条目。我想知道我是否可以用脚本来完成它

我当前的配置文件是这样的

ServerName abc.com   
some information.   
…   
……   
我想拥有这样的东西

ServerName abc.com    
CustomLog "/usr/local/logs/abc.com.log"    
some information.    
…   
……       
通过某种脚本可以吗?我有很多这样的虚拟主机条目,所以手动更新是不可能的。。有什么想法吗?

试试这个sed脚本:

sed -i~ '/^ServerName /s=^serverName \(.*\)=&\nCustomLog "/usr/local/logs/\1.log"=' config_file*

(未经测试)

Sed将快速解决以下问题:

sed 's=^ServerName \(.*\)=&\nCustomLog "/usr/local/logs/\1.log"='

编辑:我之前发布了一些其他东西,然后去测试它,我犯了一个错误。因此,我测试了choroba的答案,发现这也不太管用,所以对它进行了修正并简化了它。

事实上,当我在Mac上尝试这些答案时,没有一个对我有效,原因如下:

  • sed需要在打开和关闭括号进行分组之前使用
    \
  • \n
    放入替换模式只会插入一个
    n
  • Bakkreference
    \1
    不适用于
    a
    操作
下面是一个有效的命令:

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

awk
可以更简单地使用

awk 'NR==3{print "my log"}1' INPUT_FILE
  • NR
    是跟踪行号的内置变量
  • 您还可以使用
    -v
    变量名
    动态传递值,而不是在脚本中对其进行硬编码。例如,
    awk-v line=“$var”'NR==line{print“my log”}1'输入文件
    。在这种情况下,
    line
    是一个awk变量,
    $var
    可以是在
    awk的
    范围之外定义的bash变量
测试: 在评论中,我看到了您关于在匹配模式(本例中为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

这将在正确的服务器名后的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

谢谢你的帮助…但是它在同一行中打印,而不是在下一行中。请忽略我之前的评论…那是bsd在做垃圾。它在linux中工作。非常感谢。顺便问一下,如果我想在找到模式servername后只在3行之后添加自定义日志,我该怎么做?如果您能推荐任何关于这些命令的好教程,我也将不胜感激。。。我想知道如何捕鱼:)谢谢你。@Sangfroid你可以用
awk
来钓鱼。我添加了一个可能帮助您解决问题的解决方案。谢谢Jaypal。它做了一个小小的调整…顺便问一下,你推荐哪本书来做这样的调整?
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