awk中的/ start /,/ end / rangeexpression式有用吗?

我一直主张,你不应该使用如下的范围expression式:

/start/,/end/ 

在awk中,因为虽然它使得你只想打印匹配的文本,包括开始和结束行稍微比替代*更简单的情况:

 /start/{f=1} f{print; if (/end/) f=0} 

当你想稍微修改它来做任何事情时,它需要完整的重写或者导致重复的代码或其他不合需要的代码。 例如,如果要使用上面的第二种forms打印除范围分隔符之外的匹配文本,则只需调整它即可移动组件:

 f{if (/end/) f=0; else print} /start/{f=1} 

但是如果你开始使用/start/,/end/你需要放弃这个方法来支持我刚刚发布的内容,或者你必须写下如下内容:

 /start/,/end/{ if (!/start|end/) print } 

即重复不合要求的条件。

然后我看到一个发布的问题,需要在文件中标识最后的end ,并且在解决scheme中使用了范围expression式,我认为这似乎可能有一些价值(请参阅https://stackoverflow.com/a/21145009/ 1745001 )。

但是现在,我又回想到,根本不值得使用范围expression式,而不使用范围expression式的解决scheme在这种情况下也能起作用。

所以 – 有没有人有范例expression式实际上增加一个解决scheme明显的价值?

*我曾经使用:

 /start/{f=1} f; /end/{f=0} 

但是太多的时候,我发现我不得不另外做一些额外的事情,当f是真的和/end/被发现(或换一种方式,只有做一些事情/end/被发现如果f是真的),所以现在我只是试图坚持稍微简短一点,但更健壮和可扩展:

 /start/{f=1} f{print; if (/end/) f=0} 

有趣。 我也经常从范围expression式开始,然后切换到使用variables..

我认为这种情况可能是有用的,除了纯粹的范围情况,如果你想打印一个比赛,但只有在一定的范围内。 也因为它立即显而易见。 例如:

 awk '/start/,/end/{if(/ppp/)print}' file 

用这个input:

 start dfgd gd ppp 1 gfdg fd gfd end ppp 2 ppp 3 start ppp 4 ppp 5 end ppp 6 ppp 7 gfdgdgd 

会产生:

 ppp 1 ppp 4 ppp 5 

– 当然也可以使用:

 awk '/start/{f=1} /ppp/ && f; /end/{f=0}' file 

但时间更长,可读性更差

尽pipe/start/,/end/ rangeexpression式可以很容易地用一个条件来重新实现,但是它有很多有用的用例。 正如你观察到的那样,对于表格数据的处理可能没有什么价值, awk的主要但不仅仅是用例。

所以 – 有没有人有范例expression式实际上增加一个解决scheme明显的价值?

在上述用例中,范围expression式提高了易读性。 以下是一些示例,其中范围expression式准确地select要处理的文本。 这些只是一个例子,但有无数类似的应用程序,展示awk令人难以置信的多function性。

在一定时间范围内过滤日志

假设每个日志行以ISO时间戳开始,则下面的filter将select1小时给定范围内的所有事件:

 awk '/^2015-06-30T12:00:00Z/,/^2015-06-30T13:00:00Z/' 

从文件中提取文档

 awk '/---- begin file.data ----/,/---- end file.data ----/' 

这可以用来将资源与shell脚本捆绑在一起(使用cat ),以提取部分GPG签名的消息(使用--clearsign准备)或更一般的MIME消息。

处理LaTeX文件

范围模式可以用来匹配LaTeX环境,所以我们可以select我们目录中所有文章的摘要:

 awk '/begin{abstract}/,/end{abstract}/' *.tex 

或所有的定理,准备一个定理数据库!

 awk '/begin{theorem}/,/end{theorem}/' *.tex 

或写一个短语确保定理不包含引用(如果我们认为这是不好的风格):

 awk ' /begin{theorem}/,/end{theorem}/ { if(/\\cite{/) { c+= 1 } } END { printf("There were %d bad-style citations.\n", c) } ' 

或预处理表格