Linux:如何在文件中的分隔符之间插入缺少的文本

时间:2014-11-13 00:07:11

标签: bash

假设我们有一个文本文件,其中包含一对或多对分隔符,这些分隔符围绕各种指令。每个分隔符单独出现在一行上,如下所示:

{
   directive1
   ...
}
{ 
  directive1
  ...
}
...

请注意,开始分隔符与结束分隔符不同。使用“标准”Linux工具(sed,awk,grep,perl等),如何查看此文件并检查每对分隔符(块)是否有特定的指令(比如“DirectiveX”):如果不是存在然后将其插入该块。如果它已存在,请不要更改该特定块。

2 个答案:

答案 0 :(得分:1)

我可能会使用Perl来完成这项任务。以下脚本适用于最琐碎的情况(没有嵌套,指令永远不会与花括号在同一行):

#!/usr/bin/perl
use warnings;
use strict;

my ($inside, $found);
while (<>) {
    if (/\{/) {
        $inside = 1;
        $found  = 0;
    } elsif (/\}/) {
        print "directive\n" unless $found;
        $inside = $found = 0;
    } elsif (/directive/ and $inside) {
        $found = 1;
    }
    print;
}

答案 1 :(得分:0)

如果directiveX未显示在某个块中,则会在块的末尾打印MyDirjective

awk -v RS='\n}\n' '{print $0} /{/ {if (!/directiveX/) print "  MyDirective"; print "}"}' file

如何运作

  • -v RS='\n}\n'

    awk将文件分为“记录”。这个语句告诉awk,它自己行上的右括号是分隔两个记录。

  • print $0

    按原样打印出现有记录。

  • /{/

    这测试新块是否包括开放式支撑。如果没有,则跳过后面的命令。

  • if (!/directiveX/) print "MyDirective"

    如果现有记录不包含directiveX,则打印MyDirective。 (/directiveX/directiveX的存在以及感叹号!的测试否定了该测试。)

  • print RS

    最后,在每条记录的末尾,打印右括号(记录分隔符)。

实施例

考虑这个示例文件:

$ cat file
{
   directiveX
   ...
}
{ 
  directive1
  directive2
  ...
}
{
...
  directive3
}
...

这会在需要的地方添加MyDirective

$ awk -v RS='\n}\n' '{print $0} /{/ {if (!/directiveX/) print "  MyDirective"; print "}"}' file
{
   directiveX
   ...
}
{ 
  directive1
  directive2
  ...
  MyDirective
}
{
...
  directive3
  MyDirective
}
...