我们目前正在使用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替换日期行,所以它只是剥夺了版权。
答案 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
上述情况显然未经测试,因为您没有提供任何样本输入/输出,我们可以测试潜在的解决方案。