搜索模式中的grep,如果模式不存在则替换

时间:2013-07-04 11:29:03

标签: shell vim replace sed

我的文件格式如下:

========================================================
line1line1line1line1line1line1line1line1line1

line2-anything could be here

...anything again

++++++++++++++++++++++++++++++++++++++++++++++++++++++++

========================================================

abc abc abc bacbk kjhhjkh

line2-anything could be here SOME_STRING

...anything again

++++++++++++++++++++++++++++++++++++++++++++++++++++++++

我想搜索并替换=====*++++*之间定义的块),并说abc,其中SOME_STRING不存在。例如,上面的文件看起来像:

========================================================

abc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++

========================================================

abc abc abc bacbk kjhhjkh

line2-anything could be here SOME_STRING

...anything again

++++++++++++++++++++++++++++++++++++++++++++++++++++++++

因为第1块没有SOME_STRING

我可以使用搜索模式获取块

========================================================\_.\{-\}++++++++++++++++++++++++++++++++++++++++++++++++++++++++

但后来我想grep这个模式搜索的结果,如果grep返回1(找不到匹配项),请用abc替换该块。

有可能吗?提前谢谢。

2 个答案:

答案 0 :(得分:1)

grep不适合这个。像这样使用awk:

awk 'c &&  $0 != "++++"{ l=l $0 RS }
     /====/{ print; c=1 } 
     c && $0 == "++++"{
       if (l ~ /SOME_STRING/)
          print l $0;
       else
          print "abc" RS $0;
       c=0;
       l=""
     }' file

PS:为了显示代码,我在上面的代码中将===================++++++++++++++++截断为长度为4。

<强>解释

/====/{ print; c=1 }    - If input matches "====" then print the line and set c=1
c && !($0 ~ /\+\+\+\+/) - If c=1 and input doesn't match "++++" then don't print but append 
                          current line into a buffer (l=l $0 RS)
c && $0 ~ /\+\+\+\+/ - If c=1 and input matches then execute below block:
   if (l ~ /SOME_STRING/) - if SOME_STRING is in buffer then print buffer + current line
   else                   - print abc + current line
   c=0;l=""               - reset our variables

答案 1 :(得分:1)

我不知道如何使用来实现它,所以删除帖子以尝试使用

script.sed的内容:

## For all lines between these patterns...
/^====/,/^++++/ { 
    ## Add current line to "hold space"
    H   

    ## Process next one unless reach to end of range.
    /^++++/! { b } 

    ## Get content of "hold space"
    x   

    ## Remove leading newline added by previous "H" command.
    s/^\n//

    ## If not found the string, do the removal saving either
    ## header and footer.
    /SOME_STRING/! { 
        s/^\(=\+\n\).*\(\n+\+\)$/\1abc\2/ 
    }   

    ## Print and remove all content from both buffers.
    p   
    s/^.*$//
    x   
    s/^.*$//
}

假设以下输入文件(infile):

========================================================
line1line1line1line1line1line1line1line1line1
line2-anything could be here
...anything again
++++++++++++++++++++++++++++++++++++++++++++++++++++++++

========================================================
abc abc abc bacbk kjhhjkh
line2-anything could be here SOME_STRING
...anything again
++++++++++++++++++++++++++++++++++++++++++++++++++++++++

========================================================
abc abc abc bacbk kjhhjkh
line2-anything could be here SOME_STRING
...anything again
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
========================================================
line1line1line1line1line1line1line1line1line1
line2-anything could be here
...anything again
++++++++++++++++++++++++++++++++++++++++++++++++++++++++

像以下一样运行:

sed -nf script.sed infile

产量:

========================================================
abc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
========================================================
abc abc abc bacbk kjhhjkh
line2-anything could be here SOME_STRING
...anything again
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
========================================================
abc abc abc bacbk kjhhjkh
line2-anything could be here SOME_STRING
...anything again
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
========================================================
abc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++