sed / awk - 在跨越多行的模式之间打印文本

时间:2012-10-23 04:30:28

标签: bash sed awk

我是脚本新手,并且正在尝试学习如何提取两种不同模式之间存在的任何文本。但是,在以下情况中,我仍然无法弄清楚如何在两种模式之间提取文本:

如果我的输入文件读取:

Hi I would like
to print text
between these 
patterns

我预期的输出就像:

I would like
to print text
between these 

即。我的第一个搜索模式是“嗨”并跳过这个模式,但打印出匹配模式后面的同一行中存在的所有内容。我的第二个搜索模式是“模式”,我想完全避免打印此行或超出该行的任何行

我尝试了以下内容:

sed -n '/Hi/,/patterns/p' test.txt 

[输出]

Hi I would like
to print text
between these 
patterns 

接下来,我试过了:

`awk ' /'"Hi"'/ {flag=1;next} /'"pattern"'/{flag=0} flag { print }'` test.txt 

[输出]

to print text
between these

有人可以帮助我确定如何实现这一目标吗? 提前致谢

4 个答案:

答案 0 :(得分:6)

你有正确的想法,awk中的迷你状态机,但你需要一些轻微的mods,按照下面的记录:

pax> echo 'Hi I would like
to print text
between these 
patterns ' | awk '
    /patterns/ { echo = 0 }
    /Hi /      { gsub("^.*Hi ", "", $0); echo = 1 }
               { if (echo == 1) { print } }'

或者,以压缩形式:

awk '/patterns/{e=0}/Hi /{gsub("^.*Hi ","",$0);e=1}{if(e==1){print}}'

输出是:

I would like
to print text
between these 

按要求。

其工作方式如下。 echo变量最初为0,表示不会发生回音。

依次检查每一行。如果它包含patterns,则禁用回显。

如果它包含Hi后跟空格,则启用回显并使用 gsub来修改该行以清除{{1 }}

然后,无论如何,当Hi标志打开时,线(可能已修改)将被回显。

现在,将出现边缘情况,例如:

  • 包含两次echo次的行;或
  • Hi之前包含的行。

你还没有说明应如何处理,所以我没有打扰,但基本概念应该是相同的。

答案 1 :(得分:3)

更新了解决方案以删除“模式”行:

$ sed -n '/^Hi/,/patterns/{s/^Hi //;/^patterns/d;p;}' file
I would like
to print text
between these

答案 2 :(得分:2)

这可能适合你(GNU sed):

sed '/Hi /!d;s//\n/;s/.*\n//;ta;:a;s/patterns.*$//;tb;$!{n;ba};:b;/^$/d' file

答案 3 :(得分:1)

当你在行的开头找到+ replace Hi时,设置一个标志(f),找到模式时清除它,然后在设置标志时调用默认打印:

$ awk 'sub(/^Hi /,""){f=1} /patterns/{f=0} f'  file
I would like
to print text
between these