在多行正则表达式匹配后插入行

在多行正则表达式匹配后插入行

我有一个 XML 文件,需要附加到一组特定的标签之后。基本上文件结构如下所示:

<key>servers</key>
<dict>
... Server Details ...
</dict>

我想匹配以下几行:

<key>servers</key>
<dict>

并在 后附加指定服务器连接的 XML 块<dict>。我已将新的 XML 块放在其自己的文本文件中,因为它相当长。

我已经考虑sedawk这样做了,但我遇到了困难。我也见过使用 Perlperl来完成此任务的示例,但我对 Perl 不太熟悉。据我了解,但sed并不awk擅长多行匹配。

我需要进行多行匹配的原因是因为该<dict>标记在 XML 文件中经常使用,并且我需要在该<key>servers</key>部分中附加一个块,而不是替换其整个内容。

答案1

你可以这样做:

awk '{print}
     $0 == "<dict>" && previous == "<key>servers</key>" {
       system("cat other-file.xml")
     }
     {previous = $0}'

答案2

sed '/keys_line_1/,/keys_line_last/{/keys_line_last/{
h;s/unique_split_point.*//;r /path/to/insert/file
x;s/.*unique_split_point//;G
}}'

sed当涉及到需要对假设进行调整时,并不完全宽容。所做的一切sed都是它刚刚所做的事情的直接结果,因此细节上的一个非常小的错误可能会极大地改变结果。

这样,如果没有一点点疯狂和很大的耐心,sed脚本调试可能会是一件令人沮丧的事情,但是,考虑到这些品质,回报可能是巨大的。我高度l如果您尝试的话,建议在此过程中尽可能多地使用ook 命令。

sed ...;l;...complicated_script...;l;...

实际上,第二次看你的问题,我认为它比我第一次想象的要容易。所有你真正需要的(我认为)是将模式空间扩大一行服务器相符。默认情况下,sed每个周期仅缓冲一行,但命令NPD提供对此行为的直接控制。

事实上,我相信我最初误解了这个问题 - 我以为你想将一些文本插入一行,而不是一行块。

所以你可能需要:

sed '\|<key>servers</key>|,/<dict>/N;P
/\n<dict>/!D;s/.*\n//;r /path/to/file'

这样,除了您感兴趣的那些行之外的所有行 - 从您的范围服务器通过你的词典匹配会尽快从编辑缓冲区中删除,并且您只r在第一个之后输出目标文件词典匹配遵循您的*服务器的任何序列,并且是唯一的点文件曾经附加到输出缓冲区,直接跟随您的词典如果前面有\newline,则匹配。

答案3

像这样的东西会起作用吗?

sed '\|<key>servers</key>|{n
\|<dict>| r other-file.xml
}' file.xml

答案4

由于您添加了 Perl 标签:

perl -pE 'BEGIN{
              $/ = "<key>servers</key>\n<dict>\n"; 
              $content = `cat file.xml`
          }
          $_.=$content' your_input_file

相关内容