2016-02-09 33 views
2

之间的文本,所以我发现这个SED表达为获得独家的关键字的关键字之间的文本:使用SED获得两个关键词(而不是关键词本身)

cat example.txt | sed '/^KEYWORD1/,/^KEYWORD2/!d; //d' 

其中一例。 TXT:

do 
not 
care 
KEYWORD1 
I 
want 
this 
KEYWORD2 
do 
not 
care 

输出:

I 
want 
this 

不过,我想了解知道是什么正在用这个表达。我的理解是,使用'模式范围'(如果这是不恰当的术语,请纠正我),当您第一次匹配时设置布尔值,并且仅在布尔值为true时才执行模式范围后面的命令。

然后是//d其中//应该表示最后匹配的表达式/正则表达式。因此,它是正确的,在这种情况下,带有图案的范围,逻辑如下:!

  • 查找/^KEYWORD1/,设置布尔为true,用d命令进行不删除这条线,然后自从上次的正则表达式是/^KEYWORD1/然后//d实际上是/^KEYWORD1/d它删除此行,则进入不删3个下一行和/^KEYWORD1/没有在所述行因此没有被删除
  • 查找/^KEYWORD2/d发现
  • 布尔为真,则执行!d和然后/^KEYWORD2/d,因为这是最后的正则表达式中使用

所以在这一点上,我不知道如何前后线不打印,因为它不执行,除非模式范围标志命令(!d)设置为true。

或者确实至少看看每一行的命令,并且由于第一个命令是反向删除,它会以某种方式更改逻辑以删除模式范围bool为false的所有其他行?

任何澄清如何这个sed表达式的作品将不胜感激。我已经读了this great resource上下,但仍不完全理解表达的所有细节。

+1

如果将光标悬停在上面的sed标志上并选择info,您可以找到sed相关问题的巨大资源。也许[this](http://sed.sourceforge.net/sedfaq3.html#s3.3)链接也可能启发你。 – potong

回答

1

您的误解是这样的:/address/!d并不意味着“如果我们匹配address,请勿删除该行”;该!否定地址,即“如果我们比赛address,然后确实删除了就行了。”

所以一衬里(更好写入而不cat,顺便)

sed '/^KEYWORD1/,/^KEYWORD2/!d; //d' example.txt 

执行此:

  • /^KEYWORD1/,/^KEYWORD2/!d:对于范围/^KEYWORD1/,/^KEYWORD2/,即外的所有行,

    do 
    not 
    care 
    do 
    not 
    care 
    

    删除它们。 d跳回到脚本的开始处。这给我们留下了

    KEYWORD1 
    I 
    want 
    this 
    KEYWORD2 
    

    ,我们不希望打印KEYWORD1KEYWORD2

  • 对于这些行,我们会遇到//d,这意味着“删除最后一个匹配行”。

    KEYWORD1一行中,我们检查并删除了该行,因为它之前是匹配的。在接下来的三行中,我们经历了,但没有匹配,所以我们不删除任何东西。在KEYWORD2这一行中,我们通过并删除,因为它在–之前匹配了两个模式之间的界限。

+0

谢谢!我用cat写了它,因为我实际上是将另一个命令的输出从一个文件传输到sed和vs,但是指出了一点。 – jshort

+0

当你说'd跳回到脚本的开始'时,你是否意味着它会返回到模式范围的否定被删除后剩下的内容的开始,以便第二个命令(// d)可以通过剩下的几行? – jshort

+0

@jshort我的意思是这样的:sed处理每行的整个脚本,只有几条命令改变了标准流。 'd'为1:当前模式空间被丢弃并且不被打印,下一行被加载到模式空间并且我们跳回到第一条指令。所以“跳回”真的是为了当前的周期,而不是跳到另一条线。 –