awk / sed - 如果缺少第二个范围的地址,则生成错误

时间:2016-11-21 18:32:27

标签: awk sed

我们目前正在使用sed来过滤回归运行的输出。有时我们有一个如下所示的过滤器:

/copyright/,/end copyright/d

如果缺少end copyright,则删除文件的其余部分。我想知道是否有某种方法可以为此生成错误? awk也可以使用。我真的不想添加逐行读取文件的代码,如果它遇到EOF则会发出错误。

here's a string
copyright
2016 jan 15
end copyright
date 2016 jan 5 time 15:36
last one

如果缺少end copyright,我想收到错误消息。真正的过滤器也会用DATE替换日期行,所以它只是剥夺了版权。

3 个答案:

答案 0 :(得分:2)

如果您在开始和结束之间到达输入结束(即查看地址$),可以 说服sed生成错误,但这不会是一个非常有用的消息:

/copyright/,/end copyright/{
$s//\1/  # here
d
}

如果end copyright丢失或在最后一行,退出状态为1且有用的消息,则会出错:

  

sed:-e表达式#1,字符0:`s'命令的RHS上的无效引用\ 1

如果你在makefile中使用它,你可能希望echo首先是一个有用的消息,或者(更好)将它包装在捕获错误的东西中并生成一个更有用的消息。

我用GNU sed测试了这个;虽然如果您使用的是GNU sed,您可以更轻松地使用其有用的扩展名:

  
      
  • q [EXIT-CODE]

         

    此命令只接受一个地址。

         

    退出'sed'而不再处理任何命令或输入。注意    如果没有自动打印,则打印当前模式空间    已使用-n选项停用。返回退出代码的能力    来自'sed'脚本是一个GNU'sed'扩展名。

  •   
  • Q [EXIT-CODE]

         

    此命令只接受一个地址。

         

    此命令与“q”相同,但不会打印内容    模式空间。与“q”类似,它提供了返回退出的功能    代码给来电者。

  •   

所以你可以简单地写一下

/copyright/,/end copyright/{
$Q 42
d
}

答案 1 :(得分:0)

使用sed你可以建立一个循环:

sed -e '/copyright/{:a;/end copyright/d;N;ba;};' file

:a定义标签" a"
只有当"结束版权时,/copyright end/d才会删除模式空间。匹配
N将下一行附加到模式空间
ba跳转到标签" a"

请注意d结束循环。

通过这种方式,您可以避免在结束前删除文本。

如果您根本不想显示文字,并且在" copyright" block保持unclosed,你显然需要等待文件的结尾。您也可以使用sed将所有行存储在缓冲区空间中直到结束:

sed -n -e '/copyright/{:a;/end copyright/d;${c\ERROR MESSAGE
;};N;ba;};H;${g;p};' file

H将当前行附加到缓冲区空间
g将缓冲区空间的内容放入模式空间

文件内容仅在使用${g;p}到达最后一行时显示,否则当结束时#34;结束版权"如果缺少,则在循环内的${c\ERROR MESSAGE\n;}错误消息中更改当前行。

通过这种方式,您可以测试在将其重定向到您想要的任何内容之前返回的内容。

答案 2 :(得分:0)

永远不要使用范围表达式/start/,/end/,因为它们使得简单的代码非常简单,但是当您需要更改时,需要完全重写或重复条件。始终使用标志。请注意,由于sed不支持变量,因此它不支持标志变量,因此您不应该使用sed,而应该使用awk。

在这种情况下,您的原始代码为:

awk '/copyright/{f=1} !f; /end copyright/{f=0}' file

您的修改后的代码将是:

awk '/copyright/{f=1} !f; /end copyright/{f=0} END{if (f) print "Missing end copyright"}' file

上述情况显然未经测试,因为您没有提供任何样本输入/输出,我们可以测试潜在的解决方案。