1

我有一个格式如下的文件:

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

line2-anything could be here

...anything again

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

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

abc abc abc bacbk kjhhjkh

line2-anything could be here SOME_STRING

...anything again

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

我想用不存在的say来搜索和替换块(在=====*and之间定义)。例如,上面的文件看起来像:++++*abcSOME_STRING

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

abc

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

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

abc abc abc bacbk kjhhjkh

line2-anything could be here SOME_STRING

...anything again

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

因为块 1 没有SOME_STRING.

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

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

但后来我想 grep 此模式搜索的结果,如果 grep 返回 1(未找到匹配项),请将块替换为abc.

是否可以?提前致谢。

4

2 回答 2

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
于 2013-07-04T12:03:09.087 回答
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
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
于 2013-07-04T14:02:31.017 回答