我的文件格式如下:
========================================================
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
替换该块。
有可能吗?提前谢谢。
答案 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)
我不知道如何使用vim来实现它,所以删除帖子以尝试使用sed:
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
++++++++++++++++++++++++++++++++++++++++++++++++++++++++